Pues resulta que me estaba preguntando si mi programa sería capaz de sintetizar una simulación de barrido de resonancia a partir de modulación por distorsión de fase, siguiendo un esquema similar a este:
[ Imagen no disponible ]
Fuente:
Wikipedia - Síntesis por distorsión de fase
El principio de funcionamiento es el siguiente:
Tenemos una rampa de frecuencia base.
Tenemos una onda que varía en frecuencia pero que se sincroniza a cero cada vez que comienza la rampa. Entonces tras el salto de la rampa aparece, en la onda, un salto puesto que se sincroniza de nuevo a cero con el comienzo de la rampa.
Si invertimos la rampa para hacerla descendente y la multiplicamos por la onda, cuando esta onda vaya a saltar, la rampa hará que en el salto el valor de la onda sea 0, por lo que el salto desaparece.
En realidad la función de Rampa base puede ser cualquier función de ventana que termine en 0 (e incluso es mejor que además empieze en 0), de esa forma tenemos una onda base cuyos armónicos varían conforme varía la frecuencia de la onda del barrido, simulando el barrido de resonancia.
Entonces se me ha planteado un problema. Resulta que en mi programa no era capaz de programar este algoritmo por una sencilla razón; para poder sincronizar las 2 ondas tenía que poder detectar cuando empezaba la ventana de base, y para eso tenía que usar alguna función que me permitiera comparar valores. Bueno, pues como el evaluador de expresiones no incluía operadores lógicos y de comparación (&,|,!,>,>=,en fase deformando una senoidal en forma de barrido
>que conformará los armónicos de la señal resultante.
>
>El resultado es muy melódico.
>
>Los parametros que se pueden modificar son:
>
> Amplitud(a): Amplitud de la secuencia de salida
> Recomendado: -1 la secuencia de base. Recomendado: 0 inicio del barrido de la simulación de resonancia.
> Recomendado: 0 fín del barrido de la simulación de resonancia.
> Recomendado: 0 secuencia de salida. Recomendado 0.9991, la
> secuencia se autoamplifica hasta la saturacion.
fin
variable a,y,r,b,o,f,f1,f2,c,y1,ax,ay,ay1,dz
entrada(f,"Frecuencia Base [Hz]",440)
entrada(f1,"Frecuencia Inicial [Hz]",200);
entrada(f2,"Frecuencia Final [Hz]",10000);
entrada(a,"Amplitud",1)
entrada(r,"Amortiguamiento",0.99985)
>Inicializamos variables:
>f2 pasa a ser el incremento de f del barrido
f2=(f2-f1)/MAXITER
>b es el incremento de paso de la rampa periodica
>(la rampa pasa de 0 a 1 cada f/FM ciclos)
b=f/FM
>El contador que sincroniza la rampa con la senoidal.
c=0
>La distancia del cero con respecto al polo del filtro pasaaltos.
dz=1-(768/FM)
iterar
>calculamos la rampa periodica sumando el incremento
y=y+b
>si se llega al final de la rampa (la salida pasa a ser mayor de 1),
>se resetea el contador de la senoidal.
c=c*(yHacer el módulo de 1 en coma flotante equivale a quitar la parte entera.
y=y%1
>Creamos la rampa descendiente. Al multiplicarla después por la ascendiente
>crearemos una ventana parabólica positiva (que comienza y termina en 0 en
>cada ciclo de la frecuencia de base.
y1=1-y
>Multiplicamos la ventana por el segmento de senoidal y aplicamos ganancias.
o=a*4*y1*y*sin(2*pi*f1*c/FM)*32767
>Actualizamos el amortiguamiento como la degeneración pregresiva de la ganancia.
a=a*r
>actualizamos contador de la senoidal (se incrementará mientras la rampa no
>llegue al final).
c=c+1
>Actualizamos la f de barrido para cada punto (añadiendo el incremento).
f1=f1+f2
>Todo esto lo pasamos por el filtro pasaaltos para quitar el nivel de continua.
ay = o - ax + dz * ay1
ax = o
ay1=ay
>y grabamos la salida del filtro.
grabar(ay)
fin
[/code]
Darse cuenta que aquí la clave para sincronizar las 2 ondas es la parte de la operación (yEste script genera una senoidal cúbica
>en fase deformando una senoidal en forma de barrido
>que conformará los armónicos de la señal resultante.
>
>El resultado es muy melódico.
>
>Los parametros que se pueden modificar son:
>
> Amplitud(a): Amplitud de la secuencia de salida
> Recomendado: -1 la secuencia de base. Recomendado: 0 inicio del barrido de la simulación de resonancia.
> Recomendado: 0 fín del barrido de la simulación de resonancia.
> Recomendado: 0 secuencia de salida. Recomendado 0.9991, la
> secuencia se autoamplifica hasta la saturacion.
fin
variable a,y,r,b,o,f,f1,f2,c,y1
entrada(f,"Frecuencia Base [Hz]",440)
entrada(f1,"Frecuencia Inicial [Hz]",200);
entrada(f2,"Frecuencia Final [Hz]",10000);
entrada(a,"Amplitud",1)
entrada(r,"Amortiguamiento",0.99985)
>Inicializamos variables:
>f2 pasa a ser el incremento de f del barrido
f2=(f2-f1)/MAXITER
>El contador que sincroniza la ventana con la senoidal.
c=0
iterar
>calculamos el seno cúbico periodico y guardamos el valor anterior y1.
y1=y
y=sin(2*pi*f*ITER/FM)^3
>si se cruza por cero (y*y1 es negativo), se sincroniza la cuenta de la senoidal de barrido.
c=c*(y*y1>0)
>Multiplicamos la ventana por el segmento de senoidal y aplicamos ganancias.
o=a*y*sin(2*pi*f1*c/FM)*32767
>Actualizamos el amortiguamiento como la degeneración pregresiva de la ganancia.
a=a*r
>actualizamos contador de la senoidal de los armónicos (se incrementará mientras
>la senoidal de base no cruze por cero).
c=c+1
>Actualizamos la f de barrido para cada punto (añadiendo el incremento).
f1=f1+f2
>Grabamos la salida
grabar(o)
fin
[/code]
Aquí la clave para sincronizar es saber cuando la señal de base cruza por 0 (y eso pasa
cada vez que hay un cambio de signo entre un valor y el anterior, cuya multiplicación será menor que 0), para resetear el contador de la senoidal de barrido.
Cuando vaya actualizando el programa ya lo iré mencionando por aquí. La verdad es que no pensé en un sintetizador cuando programé este programa, sino un programa que generara secuencias de sonido a partir de funciones matemáticas iterativas, para su posterior análisis, aunque la verdad, de una cosa a otra no hay mucha diferencia, no?, además, están saliendo cosas bastante curiosas de este programa (sólo hay que ver los ejemplos listados en este post, jeje).
De todas formas el programa todavía tiene muchos fallos que tengo que corregir, y nuevas caracteristicas que tengo que implementar, como por ejemplo vectores, etc.