Primeros intentos con ondas básicas (sonido
analógico):
El proyecto en su forma definitiva se inició en septiembre de 2011,
cuando luego de algunos experimentos de síntesis de voz en BASIC de C64
y de MSX, decidí intentar una conversión lo más completa posible del
sintetizador de voz para PIC16, a una computadora de 8 bits. Dado que
me inicié en la programación con la Commodore 64 allá por 1986, que es
la plataforma que usé desde ese año hasta 1991, y que fué la primera
computadora que programé en ensamblador, me pareció la opción lógica
para comenzar una versión del programa.
El sintetizador original para PIC estaba basado en sonido digital de 8
bits y 7,1KHz de frecuencia de muestreo, con algunos sonidos generados
con tablas de ondas almacenadas, otros por medio de algoritmos, y otros
con una combinación de ambos. El sonido se emitía constantemente a una
frecuencia de muestreo fija, tal como se suele hacer en sistemas
modernos, pero esto presentaba un problema para su implementación en
computadoras de 8 bits, que no fueron diseñadas para emitir sonido
digitalizado. Se intentó entonces un enfoque distinto, que ya había
probado anteriormente en BASIC, como ya mencioné.
Las primeras pruebas en ensamblador con el SID se basaron en
"sintetizar el sintetizador", es decir, en imitar con las ondas
disponibles el sonido digital generado por el PIC. La práctica demostró
que las ondas más adecuadas eran las triangulares y el ruido, la
mayoría de los sonidos podían lograrse con uno o dos canales, excepto
uno, que requería los 3. Un problema adicional lo presentaba el control
de ADSR del SID, con tiempos mínimos muy grandes como para permitir una
modulación variada, esto hizo que la mayoría de los sonidos tuviera los
mismos parámetros de ADSR, cuando en la realidad deberían tener
variaciones. Aún así, se logró descomponer las ondas digitalizadas en
1, 2 o 3 ondas básicas, aunque la conversión fué bastante artesanal (a
ojo digamos).
El método puede entenderse mejor si tenemos en cuenta esta imagen de
ejemplo:
En esta captura se puede ver el sonido digitalizado del fonema A, que
es la onda a lograr mediante la combinación de los canales del SID
emitiendo ondas básicas. Para simplificar las cosas, decidí usar ondas
triangulares, ya que las cuadradas tienen mucha distorsión al igual que
las ondas diente de sierra con su bajada abrupta. Esto limitaba
bastante el sonido, por usar sólo ondas triangulares y ruido, y por
tener un tiempo mínimo de ataque de 2 milisegundos y uno de relajación
de 6 milisegundos, lo que imposibilitaba usar el ADSR para modular y
crear nuevas ondas, ya que el sonido entero debía durar justamente
alrededor de 8 o 9 milisegundos. De esta manera la mayoría de los
sonidos usan los tiempos mínimos de ataque y relajación, que incluso
son largos para algunos, y la única variable para sonidos de mayor
duración son el tiempo de decaimiento y el nivel de sostenimiento, que
brindan un mínimo de variedad al sonido. Normalmente debía
seleccionarse el nivel de sostenimiento máximo, lo que anulaba el
tiempo de decaimiento, ya que se alcanzaba el nivel de sostenimiento
inmediatamente, pero esto no siempre resultaba así, ya que
aparentemente el SID insistía en esperar los 6 milisegundos de
decaimiento aunque ya se hubiera alcanzado el nivel de sostenimiento.
Esto provocaba que el sonido no siempre sonara igual y hubo que hacer
algunos ajustes de tiempos para asegurarse de que se disparara
correctamente la etapa de relajación a tiempo para completar el sonido
con la duración buscada.
Volviendo a la imagen, se puede ver la onda original en verde, y unas
marcas hechas manualmente con un programa de dibujo, donde traté de
imaginar el punto medio de cada ciclo de la onda (puntos en blanco),
que luego uní con líneas. Mi idea era aproximar esa onda compleja
utilizando dos canales del SID como norma, si se necesitaba un sonido
más elaborado iba a recurrir a un tercer canal para agregar más
detalle. Tenáa entonces que determinar cuales eran las frecuencias a
colocar en cada canal del SID para que mezclando las ondas se pareciera
a lo que pretendía. Para encontrar las frecuencias usé la medición de
tiempo del GoldWave, algo no demasiado preciso porque en ese momento
medía en milisegundos, pero aceptable para esto que era un simple
experimento. Sabía el tiempo exacto del sonido de la imagen, así que si
lograba aproximar a ojo dos ondas simples que se repitieran dentro del
sonido, multiplicando esas repeticiones por la frecuencia del sonido
podría obtener las frecuencias a colocar en los canales del SID. Por el
momento iba a ignorar la amplitud de las ondas, es decir el volumen,
que se puede apreciar que varía con el tiempo, y me concentraría
solamente en averiguar las frecuencias.
Como se puede ver en la imagen, la frecuencia está expresada
indirectamente por el nombre, A#2, esto es que el sonido está calibrado
para la frecuencia de la nota A# (LA sostenido) de la segunda octava,
que según la tabla son 116.54 Hz. Si no se tiene un sonido fuente como
ese, hay que medir la duración de la captura y según eso calcular la
frecuencia.
A esta onda le ví similitud con algunos tonos telefónicos, por lo cual
parecía factible que con 2 tonos pudiera aproximarla. Cuando se mezclan
dos ondas simples, una va a tener una frecuencia mayor que la otra
(salvo que sean de la misma frecuencia, logicamente). La onda de
frecuencia mayor es la que se ve más facilmente, ya que serían las
subidas y bajadas visibles a simple vista, aunque hay que estar
acostumbrado a verlas. En este caso son 11 ciclos, así que la
frecuencia alta que iría a un canal del SID tiene una frecuencia
aproximada de 116.54 Hz x 11 = 1281.94 Hz
La frecuencia más baja es un poco más difícil de ver, pero se
manifiesta en la onda como una especie de olas donde va montada la onda
de alta frecuencia. Para aproximar a ojo la frecuencia de esa onda, y
sabiendo en este caso que la de alta frecuencia se repite 11 veces,
procedemos a seguir estos 11 ciclos marcando más o menos donde iría el
medio de los flancos de subida y bajada. Es algo así como dibujar un
horizonte que está modificado por una ondulación que queremos
determinar. Cuando tenemos los medios marcados, los unimos y obtenemos
una onda que antes era invisible, que sería la onda restante para el
otro canal del SID. Para obtener la frecuencia hay que usar un poco de
imaginación, ya que es una aproximación, pero hay que tener en cuenta
que los ciclos tienen que ser de la misma duración. Mirando la onda se
puede apreciar que hay picos cada 2.5 cuadriculas, cada 2, cada 3, así
que siguiendo este patrón se ven 6 picos, pero la distancia entre el
último y el primero (dando la vuelta, recordar que el sonido se repite)
parece ser de alrededor de 5 cuadriculas, por lo que podemos asumir que
hay un pico más que no se nota porque justo se aplanan las ondas. Como
es una aproximación, tomar 7 repeticiones sirve, y entonces la
frecuencia de esta segunda onda de baja frecuencia sería de 116.54 Hz x
7 = 815.78 Hz
Ahora ya tenemos que la onda se puede aproximar mezclando una onda
senoidal de 1281.94 Hz con otra onda senoidal de 815.78 Hz, y si bien
con esto logramos una aproximación en frecuencia, aún falta refinar un
poco la forma. Si miramos la onda de la imagen anterior, se nota que
empieza con muy bajo volumen, casi cero, y termina igual, pero va como
subiendo de volumen hasta alrededor de 1/3 del sonido, y luego baja
continuamente en los otros 2/3. Esta modulación en volumen se hace en
el SID a través del control de ADSR, por lo cual tuve que mirar las
hojas de datos y simular en GoldWave unos parámetros de ADSR que sean
válidos para lo que el SID permite y se aproximen a la forma de volumen
que veo en la onda, nuevamente "a ojo".
La modulación quedó más o menos así:
Esta envolvente lo que hace es aumentar el volumen (attack) de las dos
ondas ya calculadas hasta llegar al tope, luego bajaría ligeramente
(decay) hasta nivelarse como al 80% de volumen (sustain), se mantendría
ahí brevemente y luego comenzaría a caer hasta cero (release). Con esos
parámetros de envolvente, más las dos frecuencias de las ondas
calculadas, ya se puede generar un sonido completamente sintético que
se aproxime al original. Pero dado que el SID no dispone de onda
senoidal, tenemos que usar la más aproximada que es la triangular. No
tengo capturas de los pasos intermedios, pero simulando eso en GoldWave
quedaría algo así, usando las dos ondas triangulares mezcladas y luego
aplicando la envolvente:
En esta captura puede verse abajo la onda original, y arriba la onda
simulada tal como la generaría el SID con los cálculos aproximados que
vimos, se puede notar que es una buena aproximación a la forma y
volumen.