00001 /**********************************************************/ 00002 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00003 /* 00004 Copyright: 1994 - Grupo de Voz (DAET) ETSII/IT-Bilbao 00005 00006 Nombre fuente................ SPL9.C 00007 Nombre paquete............... SPL 00008 Lenguaje fuente.............. C (Borland C/C++ 3.1) 00009 Estado....................... En desarrollo 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 1.1.2 24/07/95 Borja correccion nombre funcion bk?_fi2fc 00018 1.1.1 30/07/95 Borja scope funciones explicito 00019 1.1.0 08/12/94 Borja revision general (tipos,idx,nel,tnel...) 00020 1.0.0 18/12/93 Borja Codificacion inicial sin concluir 00021 00022 ======================== Contenido ======================== 00023 Gestion de bloques de vectores de voz (tramas y ventanas). 00024 00025 00026 . longitud o 00027 . desplazamiento 00028 . de trama {fl} 00029 . |<-------->| 00030 . | | 00031 . trama 0 | trama 1 | trama 2 trama 3 {fn} (tramas) 00032 . |----------|----------|----------|----------|----------|----------> 00033 . 0 \ / 3*{fl} 4*{fl} {n} (muestras) 00034 . \ ventana 1 / 00035 . \__________/ 00036 . ventana de 00037 . longitud {wl} 00038 00039 00040 Codigos para los nombres (unidades entre parentesis). 00041 Las unidades comienzan en 0 (la primera trama es la 0, la primera 00042 muestra es la 0). 00043 00044 . {bk} Abreviatura de bloque (-) 00045 . {fr} Abreviatura de 'trama' (-) 00046 . {fs} Comienzo de trama (muestras) 00047 . {fe} Fin de trama (muestras) 00048 . {fc} Centro de la trama (muestras) 00049 . {fl} Longitud (desplazamiento) de trama (muestras) 00050 . {fi} Numero de trama, con primera trama=0 (trama) 00051 . {fn} cantidad de tramas, con una trama=1 (tramas) 00052 00053 . {wi} Abreviatura de 'ventana' (-) 00054 . {ws} Comienzo de ventana (muestras) 00055 . {we} Fin de ventana (muestras) 00056 . {wc} Centro de la ventana (muestras) 00057 . {wl} Longitud de la ventana de analisis (muestras) 00058 . {wi} Numero de ventana, con primera ventana=0 (ventana) 00059 . {wn} cantidad de ventanas, con una ventana=1 (ventanas) 00060 00061 . {n} Cantidad de muestras, con {n}=0 para 0 muestras (muestras) 00062 . {i} Numero de muestra, con {i}=0 para la primera muestra (muestras) 00063 00064 Hay 3 conjuntos de funciones 00065 00066 . bk_???() funciones generales sobre bloques (tramas/ventanas) 00067 . bki_???() funciones sobre tramas/ventanas para trabajar con 00068 . numeros enteros tipo SPL_INT. 00069 . bkd_???() funciones sobre tramas/ventanas para trabajar con 00070 . valores generalizados de tipo SPL_FLOAT. Ademas imponen 00071 . menos restricciones (assert) a los parametros de entrada. 00072 00073 Por ejemplo, el valor {fc} que indica cual es el centro de una trama, 00074 puede estar entre dos muestras (trama de longitud par). Las 00075 funciones bki_???() utilizan este valor redondeado hacia abajo (la muestra 00076 inferior) mientras que las funciones bkd_???() utilizan el valor exacto 00077 con decimales). Por poder, hasta admiten tramas de longitud no entera, 00078 aunque no tenga mucho sentido... 00079 Otro ejemplo para bkd_???(): para un desplazamiento {fl}=5 muestras, 00080 la muestra {i}=2 esta en la trama {fi}=0, la muestra {i}=7, en la trama 00081 {fi}=1, la muestra {i}=3 esta en la 'trama' {fi}=0.2, y la 'muestra' 00082 {i}=4.5 esta en la 'trama' {fi}=0.5. 00083 00084 Definir NDEBUG para desconectar la validacion de parametros 00085 con assert(). No definir este simbolo mientras se depuren 00086 aplicaciones, ya que aunque las funciones son algo mas lentas, 00087 el chequeo de validacion de parametros resuelve muchos problemas. 00088 =========================================================== 00089 */ 00090 /*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\*/ 00091 /**********************************************************/ 00092 00093 #include "spli.h" 00094 00095 /**********************************************************/ 00096 /* calcula el entorno necesario para un analisis por tramas. Dada 00097 la longitud de trama en {fl} (desplazamiento), la longitud de 00098 la ventana de analisis en {wl}, y si la trama de desplazamiento 00099 necesita unas 'alas' anterior y posterior de {prefr} y {posfr}, 00100 y la ventana de analisis unas alas anterior y posterior de {prewi} y 00101 {poswi}, esta funcion calcula en {tprefr} cuantas muestras deben 00102 almacenarse en un buffer por delante de la primera muestra de la trama, 00103 en {tposfr} cuantas deben almacenarse por detras, y de forma similar 00104 indica en {tprewi} cuantas muestras hay en ese mismo buffer antes 00105 de la primera muestra de la ventana, y en {tposwi} cuantas hay por 00106 detras. En cualquier caso, tanto para la trama como para la ventana 00107 el buffer debe ser de la misma longitud, por lo que 00108 00109 . {tprefr}+{fl}+{tposfr} == {tprewi}+{wl}+{tposwi} 00110 00111 {wl} puede ser mayor o menor que {fl}, y todos los parametros 00112 deben ser mayores o iguales que cero, excepto {fl} que debe 00113 ser mayor que cero. 00114 Cuando la ventana no encaje de forma simetrica con una trama (porque 00115 {wl} y {fl} son de diferente paridad) entonces la ventana SIEMPRE se 00116 redondea hacia abajo, tanto si es mayor como si es menor que la trama. 00117 Si no interesa alguno de los valores de retorno ({tprefr},{tposfr}, 00118 {tprewi},{tposwi} enviar puntero NULL en su lugar. 00119 00120 La funcion {devuelve} la diferencia en muestras entre el comienzo de 00121 la trama y el comienzo de la ventana para un desplazamiento {fl} y una 00122 longitud de ventana {wl}. 00123 El valor devuelto indica el numero de muestras que hay que RESTAR a 00124 un comienzo de trama {fs} para obtener el comienzo de ventana {ws}. 00125 Por tanto, si el valor devuelto es positivo la ventana comienza antes 00126 que la trama, si es negativo la ventana comienza despues de la trama, 00127 y si es nulo, comienzan en la misma muestra. 00128 Este valor es tambien facilmente calculable a partir de los otros valores 00129 devueltos por la funcion (vale {tprefr}-{tprewi}). */ 00130 00131 PUBLIC SPL_INT XAPI bki_env( SPL_INT fl, SPL_INT prefr, SPL_INT posfr, 00132 SPL_INT wl, SPL_INT prewi, SPL_INT poswi, 00133 SPL_pINT tprefr, SPL_pINT tposfr, 00134 SPL_pINT tprewi, SPL_pINT tposwi ) 00135 { 00136 SPL_INT pre, pos, ppre, ppos; 00137 assert(fl>0); 00138 assert(prefr>=0); 00139 assert(posfr>=0); 00140 assert(wl>=0); 00141 assert(prewi>=0); 00142 assert(poswi>=0); 00143 00144 if (fl<wl) { /* desp.vent<long.vent. */ 00145 ppos = (SPL_INT)(wl-fl)/(SPL_INT)2; /* ventana tras trama */ 00146 ppre = wl-fl-ppos; /* ventana antes trama */ 00147 pos = ppos+poswi; /* total ventana despues trama */ 00148 pre = ppre+prewi; /* total ventana antes trama */ 00149 if (pos<posfr) /* mas despues trama si hace falta */ 00150 pos = posfr; 00151 if (pre<prefr) /* mas antes trama si hace falta */ 00152 pre = prefr; 00153 if (tprefr!=NULL) 00154 *tprefr = pre; 00155 if (tposfr!=NULL) 00156 *tposfr = pos; 00157 if (tprewi!=NULL) 00158 *tprewi = pre-ppre; 00159 if (tposwi!=NULL) 00160 *tposwi = pos-ppos; 00161 00162 return ppre; 00163 } 00164 else { /* desp.vent>=long.vent */ 00165 ppre = (SPL_INT)(fl-wl)/(SPL_INT)2; /* trama antes ventana */ 00166 ppos = fl-wl-ppre; /* trama tras ventana */ 00167 pos = ppos+posfr; /* total trama despues ventana */ 00168 pre = ppre+prefr; /* total trama antes ventana */ 00169 if (pos<poswi) /* mas despues ventana si hace falta */ 00170 pos = poswi; 00171 if (pre<prewi) /* mas antes ventana si hace falta */ 00172 pre = prewi; 00173 if (tprefr!=NULL) 00174 *tprefr = pre-ppre; /* trama empieza en antes-trama antes ventana */ 00175 if (tposfr!=NULL) 00176 *tposfr = pos-ppos; /* trama termina en despues-trama tras ventana */ 00177 if (tprewi!=NULL) 00178 *tprewi = pre; /* ventana empieza en antes ventana */ 00179 if (tposwi!=NULL) 00180 *tposwi = pos; 00181 00182 return -ppre; 00183 } 00184 } 00185 00186 /**********************************************************/ 00187 /* {devuelve} el numero de tramas de longitud {fl} (desplazamiento) 00188 que se pueden obtener a partir de un vector de {n} muestras. 00189 La ultima trama, en general, no estara completa. 00190 {n}>=0, {fl}>0 */ 00191 00192 PUBLIC SPL_LONG XAPI bki_n2fn( SPL_INT fl, SPL_LONG n ) 00193 { 00194 assert(n>=0); 00195 assert(fl>0); 00196 00197 return (SPL_LONG)((n+fl-1)/fl); 00198 } 00199 00200 /**********************************************************/ 00201 /* {devuelve} el numero de muestras que se pueden obtener a partir 00202 de {fn} tramas de longitud {fl} muestras cada una, aunque si 00203 la ultima trama no esta completa, el numero puede ser menor. 00204 {fn}>=0, {fl}>0 */ 00205 00206 PUBLIC SPL_LONG XAPI bki_fn2n( SPL_INT fl, SPL_LONG fn ) 00207 { 00208 assert(fl>0); 00209 assert(fn>=0); 00210 00211 return (SPL_LONG)(fl*fn); 00212 } 00213 00214 /**********************************************************/ 00215 /* {devuelve} la muestra en la que comienza la trama numero {fi} 00216 para un desplazamiento de trama {fl}. 00217 {fl} > 0 */ 00218 00219 PUBLIC SPL_LONG XAPI bki_fi2fs( SPL_INT fl, SPL_LONG fi ) 00220 { 00221 assert(fl>0); 00222 00223 return (SPL_LONG)(fl*fi); 00224 } 00225 00226 /**********************************************************/ 00227 /* {devuelve} la muestra en la que termina la trama numero {fi} 00228 para un desplazamiento de trama {fl}. 00229 {fl} > 0 */ 00230 00231 PUBLIC SPL_LONG XAPI bki_fi2fe( SPL_INT fl, SPL_LONG fi ) 00232 { 00233 assert(fl>0); 00234 00235 return (SPL_LONG)(fl*(fi+1)-1); 00236 } 00237 00238 /**********************************************************/ 00239 /* {devuelve} la muestra central (redondeada hacia abajo) de 00240 la trama numero {fi} para un desplazamiento de trama {fl}. 00241 {fl} > 0 */ 00242 00243 PUBLIC SPL_LONG XAPI bki_fi2fc( SPL_INT fl, SPL_LONG fi ) 00244 { 00245 assert(fl>0); 00246 00247 return (SPL_LONG)(fl*fi+(SPL_LONG)((fl-1)/2)); 00248 } 00249 00250 /**********************************************************/ 00251 /* {devuelve} la trama en la que esta situada la muestra {i} 00252 para un desplazamiento de trama {fl}. 00253 {fl} > 0 */ 00254 00255 PUBLIC SPL_LONG XAPI bki_i2fi( SPL_INT fl, SPL_LONG i ) 00256 { 00257 assert(fl>0); 00258 00259 return (SPL_LONG)(i/fl); 00260 } 00261 00262 /**********************************************************/ 00263 /* similar a bli_env() pero utiliza valores fraccionarios. 00264 Ademas no impone restricciones a los parametros de entrada */ 00265 00266 PUBLIC SPL_FLOAT XAPI bkd_env( SPL_FLOAT fl, SPL_FLOAT prefr, 00267 SPL_FLOAT posfr, SPL_FLOAT wl, SPL_FLOAT prewi, SPL_FLOAT poswi, 00268 SPL_pFLOAT tprefr, SPL_pFLOAT tposfr, 00269 SPL_pFLOAT tprewi, SPL_pFLOAT tposwi ) 00270 { 00271 SPL_FLOAT pre, pos, ppre, ppos; 00272 00273 if (fl<wl) { /* desp.vent<long.vent. */ 00274 ppos = (wl-fl)/2.0; /* ventana tras trama */ 00275 ppre = wl-fl-ppos; /* ventana antes trama */ 00276 pos = ppos+poswi; /* total ventana despues trama */ 00277 pre = ppre+prewi; /* total ventana antes trama */ 00278 if (pos<posfr) /* mas despues trama si hace falta */ 00279 pos = posfr; 00280 if (pre<prefr) /* mas antes trama si hace falta */ 00281 pre = prefr; 00282 if (tprefr!=NULL) 00283 *tprefr = pre; 00284 if (tposfr!=NULL) 00285 *tposfr = pos; 00286 if (tprewi!=NULL) 00287 *tprewi = pre-ppre; 00288 if (tposwi!=NULL) 00289 *tposwi = pos-ppos; 00290 00291 return ppre; 00292 } 00293 else { /* desp.vent>=long.vent */ 00294 ppre = (fl-wl)/2.0; /* trama antes ventana */ 00295 ppos = fl-wl-ppre; /* trama tras ventana */ 00296 pos = ppos+posfr; /* total trama despues ventana */ 00297 pre = ppre+prefr; /* total trama antes ventana */ 00298 if (pos<poswi) /* mas despues ventana si hace falta */ 00299 pos = poswi; 00300 if (pre<prewi) /* mas antes ventana si hace falta */ 00301 pre = prewi; 00302 if (tprefr!=NULL) 00303 *tprefr = pre-ppre; /* trama empieza en antes-trama antes ventana */ 00304 if (tposfr!=NULL) 00305 *tposfr = pos-ppos; /* trama termina en despues-trama tras ventana */ 00306 if (tprewi!=NULL) 00307 *tprewi = pre; /* ventana empieza en antes ventana */ 00308 if (tposwi!=NULL) 00309 *tposwi = pos; 00310 00311 return -ppre; 00312 } 00313 } 00314 00315 /**********************************************************/ 00316 /* {devuelve} el numero de tramas de longitud {fl} (desplazamiento) 00317 que se pueden obtener a partir de un vector de {n} muestras. 00318 El valor devuelto puede ser fraccionario, ya que la ultima trama, 00319 en general, no estara completa. 00320 {fl}!=0 */ 00321 00322 PUBLIC SPL_FLOAT XAPI bkd_n2fn( SPL_FLOAT fl, SPL_FLOAT n ) 00323 { 00324 assert(fl!=0.0); 00325 00326 return (n/fl); 00327 } 00328 00329 /**********************************************************/ 00330 /* {devuelve} el numero de muestras que se pueden obtener a partir 00331 de {fn} tramas de longitud {fl} muestras cada una. Si 00332 la ultima trama no esta completa, {fn} puede ser fraccionario. */ 00333 00334 PUBLIC SPL_FLOAT XAPI bkd_fn2n( SPL_FLOAT fl, SPL_FLOAT fn ) 00335 { 00336 return (fl*fn); 00337 } 00338 00339 /**********************************************************/ 00340 /* {devuelve} la muestra en la que comienza la trama numero {fi} 00341 para un desplazamiento de trama {fl} */ 00342 00343 PUBLIC SPL_FLOAT XAPI bkd_fi2fs( SPL_FLOAT fl, SPL_FLOAT fi ) 00344 { 00345 return (fl*fi)-0.5; 00346 } 00347 00348 /**********************************************************/ 00349 /* {devuelve} la muestra en la que termina la trama numero {fi} 00350 para un desplazamiento de trama {fl} */ 00351 00352 PUBLIC SPL_FLOAT XAPI bkd_fi2fe( SPL_FLOAT fl, SPL_FLOAT fi ) 00353 { 00354 return (fl*(fi+1.0)-0.5); 00355 } 00356 00357 /**********************************************************/ 00358 /* {devuelve} la muestra central de la trama numero {fi} para un 00359 desplazamiento de trama {fl}. */ 00360 00361 PUBLIC SPL_FLOAT XAPI bkd_fi2fc( SPL_FLOAT fl, SPL_FLOAT fi ) 00362 { 00363 return (fl*fi+((fl-1.0)/2.0)); 00364 } 00365 00366 /**********************************************************/ 00367 /* {devuelve} la trama (fraccionaria) en la que esta situada 00368 la muestra {i} para un desplazamiento de trama {fl}. 00369 {fl}!=0 */ 00370 00371 PUBLIC SPL_FLOAT XAPI bkd_i2fi( SPL_FLOAT fl, SPL_FLOAT i ) 00372 { 00373 assert(fl!=0.0); 00374 00375 return (i-(fl-1.0)/2.0)/fl; 00376 } 00377 00378 /**********************************************************/ 00379