Es más que probable que el largo de la onda periódica sea mayor que el largo de la tabla de valores usada para generarla. Según en que lugar de la onda nos encontremos, el valor será o estará cercano a uno de la tabla de valores. El que no necesariamente haya coincidencia entre estos lugares de la onda con uno de la tabla, se debe a la relación entre el largo de la tabla y la frecuencia de muestreo. Si éstas dos son iguales, entonces la relación es 1, y significa que por cada muestra en la onda hay una muestra de la tabla, entonces si coincidirán los valores. Pero si la relación es ½, entonces el largo de la tabla es la mitad de la frecuencia de muestreo, y la onda se leerá dos veces por cada vez que se lee la tabla de valores, por lo tanto debemos obtener ese valor intermedio mediante algún recurso. Para eso usamos interpolación lineal.
Creamos una función que nos dé el valor actual.
El valor actual de la onda periódica.
El proceso es muy simple aquí, dado que todo el trabajo lo hace la función interpoladora. Ésta función devolverá un valor que depende del lugar actual y tiene que ver con que el conjunto de valores es periódico. Obtengo el valor actual de la onda multiplicando la amplitud por el valor que devuelve dicha función interpoladora.
El usar un puntero a función nos permite definir cualquier tipo de interpolación, sólo debemos tener en cuenta los argumentos y saber que la onda siempre es periódica. La interpolación usada en textura es del tipo lineal, la cual se explica en el apéndice; pero como ésta explicación difiere un poco de la usada aquí, mostramos la función. Es fácil ver la diferencia, ésta toma en cuenta la periodicidad de la onda, mientras que la otra es más genérica. Por lo tanto, una vez que obtenemos el lugar siguiente en la tabla, nos cuidamos que esté más allá del tamaño de la misma. Si es así, realizamos un bucle restando al lugar siguiente el tamaño hasta estar dentro de la tabla.
Función que obtiene el valor actual de la tabla:
Función que interpola linealmente:
float ValorActualOnda(float amp, float *tabla, int tam, float lg_act, float (*Interp)(float *, int, float)) { float val_act; val_act = amp * Interp(tabla, tam, lg_act); return val_act; } /* La función que interpola, usada por textura */ float InterpLineal(float *tabla, int tam, float lg_act) { float val_act; int lg_ant, lg_sig; lg_ant = (int)lg_act; lg_sig = lg_ant + 1; while(lg_sig >= tam) lg_sig -= tam; val_act = (tabla[lg_ant] + ((tabla[lg_sig] - tabla[lg_ant]) * (lg_act - lg_ant))); return val_act; }
Anterior | Inicio | Siguiente |
Lugar actual en la tabla | Envolvente |