PARTE 6: UN CAMBIO DE TONO
El título de esta columna tiene un doble significado. El significado original tiene que ver con el tema que nos ocupa: formas de onda personalizadas en el Atari. Últimamente ha habido mucho interés en el tema, y con razón. La configuración de ondas personalizada puede producir efectos de sonido realistas, buenas imitaciones instrumentales y probablemente una de las modas más populares en la industria en este momento, la síntesis de voz. Es un tema maduro para una serie sobre generación de sonido.
Todas estas técnicas, sin embargo, dependen en gran medida del lenguaje Ensamblador. Los lenguajes de alto nivel no son lo suficientemente eficientes para llevar al altavoz a las frecuencias necesarias. Además, a medida que sigamos ampliando la gama de sonidos disponibles para nosotros, seguiremos encontrándonos con esta situación. De ahí el segundo significado del título: El tono de esta columna va a inclinarse seriamente hacia el lenguaje Ensamblador.
Esto no debería ser motivo de pánico entre los programadores BASIC. Se hará todo lo posible para proporcionar un código híbrido que le resulte útil o interesante. Este mes es un buen ejemplo: el listado BASIC proporciona un método conveniente para producir ondas sinusoidales que podrían adaptarse fácilmente para diferentes propósitos. Si está familiarizado con el Ensamblador, por supuesto, podrá experimentar más plenamente con formas de onda personalizadas.
Así termina la editorial. Hablemos de sonido.
De nuestra discusión anterior sobre la cancelación de formas de onda, debería tener una idea de lo que es una onda sonora: una serie rítmica de pulsos en el aire. La forma de cada pulso es lo que llamamos forma de onda y determina el carácter del sonido. Para hacer una generalización amplia, las formas de onda con bordes afilados suenan más zumbantes o más ásperas que las formas de onda con bordes redondeados. Cualquiera interesado en obtener una gama más amplia de tonos del Atari, entonces, debería interesarse por la generación de formas de onda personalizadas, ya que ofrece un mayor control sobre el carácter de un sonido.
Si tiene problemas para visualizar lo que hace una forma de onda, repasemos con un ejemplo que todos conocemos y amamos, el parámetro 10 de distorsión de tono puro del Atari. La salida de forma de onda normal con esta configuración es una onda cuadrada, una forma simple formada por arriba/abajos o encendido/apagados que se adapta perfectamente a la electrónica digital. Cuando se traduce al altavoz, una onda cuadrada implica (1) comenzar completamente retraída; (2) instantáneamente extenderse por completo; (3) instantáneamente volver a retraerse por completo.
Lo cual, dicho sea de paso, es la razón por la que realmente no se escucha una verdadera onda cuadrada. La transmisión de materia aún no se ha inventado y el altavoz no puede realmente saltar de un punto del espacio a otro. Sin embargo, se mueve allí lo más rápido que puede y el sonido es más o menos el mismo.
El punto clave a tener en cuenta es que una forma de onda es un conjunto de "instrucciones" para el cono del altavoz que tienen que ver con su patrón de movimiento. Cuando enviamos una forma de onda al altavoz, éste baila hacia adelante y hacia atrás al compás de la forma de onda que le damos. Este cono de papel vibrante empuja el aire, el que a su vez empuja una membrana en nuestro oído. El objetivo de la generación de sonido, entonces, es ofrecer un patrón interesante de movimiento hacia adelante y hacia atrás a nuestro tímpano. Afortunadamente, un altavoz puede ocupar más de dos posiciones, por lo que puede reproducir millones de patrones además de encendido/apagado/encendido/apagado. Digamos que nuestro altavoz tiene dieciséis posiciones diferentes, siendo 0 completamente retraído y 15 completamente extendido. Producir diferentes formas de onda implicaría enviar una serie repetitiva de números entre 0 y 15. El patrón de números determinaría la forma de onda y, por tanto, el carácter del tono. El tono o frecuencia del sonido dependería de la rapidez con la que se repitiera la secuencia. Las secuencias más rápidas ocurren en una frecuencia más alta y por lo tanto tienen un tono más alto.
Como ya podrá adivinar, Atari nos proporciona una manera de comunicarnos directamente con el cono del altavoz y entregar nuestro patrón de "instrucciones" o nuestra propia forma de onda. Al configurar el bit 4 en AUDCX, habilitamos un modo especial llamado salida forzada, el que pasa el parámetro de volumen directamente al altavoz en forma de un voltaje fijo. De esta manera podemos hacer que el altavoz baile en cualquier patrón que queramos (dentro de unos límites muy definidos).
Si no recuerda AUDCX, es el registro de control de audio para cada voz, denominado AUDC1 (dirección $D201), AUDC2 ($0203), etc. El nibble superior de AUDCX contiene el parámetro de distorsión para el canal, y el nibble inferior contiene la información del volumen. Un tono puro de volumen 8, por ejemplo, es $A8, el $A (10 decimal) para tono puro, el 8 para volumen. La implementación de salida forzada simplemente implica almacenar un valor entre $10 y $1F en el registro AUDC de un canal. Un valor de $10 retrae el altavoz, $1F lo extiende completamente y los valores entre estos extremos colocan al altavoz en una posición media correspondiente.
Por ejemplo, almacenar sucesivamente los valores $10, $1F, $10, $1F... en AUDC1 producirá la onda cuadrada normalmente producida por el ajuste de tono puro en el canal 1. (Excepto que será el resultado de su propio trabajo, y ¡por lo tanto sonará mucho mejor!) Una secuencia más interesante podría ser:
lo que produciría una onda de rampa (o de sierra).
Sin embargo, existen algunas desventajas de la salida forzada que debe tener en cuenta. La primera es importante: el tiempo del procesador. Para producir una alta frecuencia, el 6502 debe dedicar todos sus recursos a la producción de la forma de onda. Esto significa que su programa se detendrá cada vez que desee cantar. No hay cambios gráficos, nada. Sin embargo, esa no es toda la historia. Para producir una forma de onda sin distorsión, todas las interrupciones deben estar desactivadas, al igual que todo DMA.
Si no está familiarizado con estos términos, se refieren a eventos que interrumpen momentáneamente la ejecución del programa por parte del 6502. Cada vez que se presiona una tecla, se produce una interrupción del teclado y el 6502 guarda toda la información con la que estaba trabajando, salta a un programa para manejar la interrupción y luego regresa a su programa después de recuperar la información que guardó. Es como leer un libro durante una conversación: siempre estás poniendo un dedo en la página para poder responder una pregunta. No se puede leer mucho de esta manera y el 6502 no se puede realizar mucha computación. DMA significa Direct Memory Access (Acceso Directo a Memoria) y ocurre cada vez que se genera la visualización en pantalla. ANTIC (el chip que maneja la pantalla) detiene el 6502 para que pueda tomar prestadas las líneas de dirección y datos. Estas constantes interrupciones crean "interrupciones" de zumbidos en la forma de onda que deben detenerse.
¿Qué significa esto para el usuario? Bueno, fealdad. Cada vez que se ingresa a la rutina de sonido, la pantalla parpadea y es reemplazada por el color de fondo. Si el color de fondo es negro, se parece mucho a un fallo del sistema. Además, si se entra y sale de la rutina repetidamente, como en la demostración, el parpadeo distraerá a todos menos a un ciego.
¿Qué se puede hacer al respecto? Muy poco. Es útil almacenar el color normal de la pantalla (en los gráficos 0, $94) en el registro de fondo. Esto significa que sólo el texto parpadea. Sí, sigue siendo feo.
También existen otras limitaciones. El uso de la memoria es uno de ellos. La síntesis de voz se mencionó anteriormente como un derivado del modo de salida forzada; La idea de la síntesis de voz sin tener que comprar ningún periférico adicional es realmente apasionante, y actualmente existen algunos programas en el mercado que hacen exactamente eso. Desafortunadamente, los requisitos de almacenamiento de datos, incluso para una simple oración, son asombrosos, y el programador serio debe considerar cuidadosamente qué opciones renunciará para tener una mayor fidelidad de la salida de voz. Una gran cantidad de código de máquina puede caber en el espacio reservado para "¡Te tenemos, basura terrestre!" Esto no quiere decir que la síntesis de voz no tenga cabida en el Atari, sólo que se debe realizar un examen de conciencia serio antes de tomar la decisión.
El Programa de Ejemplo. La demostración muestra un uso más modesto de la salida forzada: proporciona una manera de reproducir formas de onda personalizadas desde BASIC. Tal como está escrito, la demostración reproduce ondas sinusoidales, que son considerablemente más relajantes que las ondas cuadradas y deberían ser un cambio de tono bienvenido para aquellos que no son programadores en su casa.
El listado en Ensamblador está completamente comentado y debería ser fácil de seguir. Acepta una tabla de longitud de onda, duración de nota y frecuencia desde el BASIC. La tabla de ondas se fija en la página 6 y puede tener una longitud máxima de 256 pasos. La duración y la frecuencia también pueden ser cualquier número entre 0 y 255.
;*********************** ;* Forced Output Demo * ;* Assembler Listing * ;*********************** NMIEN = $D40E IRQEN = $D20E DMACTL = $D400 AUDC = $D201 AUDCTL = $D208 SKCTL = $D20F COLBK = $D01A DUMMY = $D01E ; WVTAB = $600 ; ORG $CB WVTL DS 1 DURA DS 2 WVPNT DS 1 WFREQ DS 1 WCNT DS 1 ; ORG $4000 ;(relocatable) ; PLA;number of args PLA;wave table length hi PLA;wave table length In STA WVTL PLA;duration hi PLA;duration lo STA DURA+1 PLA;freq hi PLA;freq lo STA WFREQ;store freq STA WCNT LDA #0;init pointer STA WVPNT ;no interrupts, no DMA STA NMIEN STA IRQEN STA DMACTL ;init audio STA AUDCTL STA DURA LDA #3 STA SKCTL ;color the screen LDA #$94 STA COLBK ; PLAYIT DEC WCNT;dec freq cnt BEQ DOVOX ;waste some machine cycles LDX #5 WASTE DEX BNE WASTE STA DUMMY,X BEQ UPDUR DOVOX LDA WFREQ ;recharge cnt STA WCNT ;get index into wave table LDY WVPNT ;get volume and set force output LDA WVTAB,Y ORA #$10 ;punch the speaker STA AUDC ;move the wave pointer INY ;check for table end CPY WVTL BCC NOWRAP ;wrap pointer LDY #0 NOWRAP STY WVPNT ;update duration counter UPDUR DEC DURA BNE PLAYIT DEC DURA+1 BNE PLAYIT ;time's up, return to Basic LDA #$FF STA NMIEN STA IRQEN RTS ; END
No se utilizan trucos reales en el código, pero observe la ubicación del mecanismo de retardo: es importante colocar el retardo entre cada paso de la forma de onda, para que se conserve la forma de onda. También tenga en cuenta que si aún no se ha alcanzado el tiempo para generar otro paso de onda, se ingresa un pequeño retraso para ecualizar el tiempo de ejecución del bucle.
Hay dos factores de distorsión: cada 256 iteraciones, se utilizan 7 ciclos de máquina adicionales para actualizar el byte alto del recuento de duración, y cada vez que se repite la forma de onda, se utilizan 2 ciclos adicionales. Los puristas pueden estremecerse, pero cuando el 6502 funciona a 1,79 MHz, los ciclos perdidos son mínimos.
Tenga en cuenta también que la parte del Ensamblador fuerza el bit 4 de AUDCX a 1, de modo que BASIC pueda pasar los bits de volumen a través de la tabla de formas de onda. Configurar un bit específico es mucho más fácil en Ensamblador que en BASIC.
La rutina BASIC primero coloca el Código de Máquina en su lugar (líneas 29 a 50) y luego compila la tabla de formas de onda. La fórmula utilizada formará una onda sinusoidal compuesta de LNG pasos. El valor de LNG se puede cambiar (línea 9) a cualquier valor hasta 255. Cuanto mayor sea la tabla de formas de onda, mayor será la resolución de la onda sinusoidal y, por lo tanto, representará con mayor precisión una onda sinusoidal verdadera (en términos más subjetivos). Sin embargo, a medida que la forma de onda se alarga, la frecuencia más alta disminuye, porque hay más pasos que cubrir antes de que la forma se repita. Las ondas sinusoidales suenan mejor en frecuencias más altas, por lo que las longitudes de onda largas no son muy útiles con esta fórmula. Otras formas de onda funcionan mucho mejor en las frecuencias más bajas; pruebe la forma de onda de rampa discutida anteriormente.
Después de introducir la forma de onda, BASIC lee una frecuencia de la tabla de datos en las líneas 26 y 27 y llama al controlador del altavoz en Lenguaje de Máquina.
La demostración se puede modificar fácilmente para diferentes formas de onda; simplemente introduzca la secuencia deseada desde las ubicaciones 1536 a 1791. Las formas de onda se pueden leer desde una tabla de datos o ingresar con cualquier esquema de edición extraño que se le ocurra. Aquí hay mucho potencial para la experimentación, incluso sin profundizar en la parte del Ensamblador.
Oh sí; Recuerde siempre guardar el código híbrido antes de ejecutarlo. Un solo error en las declaraciones de datos del Código de Máquina probablemente devorará el programa, el sistema operativo, DOS, su gato...
1 REM ************************* 2 REM * FORCED OUTPUT DEMO * 3 REM * BY BILL WILLIAMS * 4 REM * BASIC LISTING * 5 REM ************************* 7 GOSUB 29 8 SETCOLOR 4,9,4 9 LNG=10:TEMPO=10 10 ? "WAVESHAPE:" 11 FOR L=0 TO LNG-1 12 N=INT(SIN(L*6.2831853/LNG)*7)+7 13 POKE 1536+L,N 14 ? N;" "; 15 NEXT L 16 FOR REPEAT=1 TO 4 17 RESTORE 25 18 FOR MELODY=1 TO 14 19 READ N 20 Q=USR(ADR(QQQ$)+1,LNG,TEMPO,N) 21 NEXT MELODY 22 NEXT REPEAT 23 END 25 REM MELODY NOTES 26 DATA 2,16,8,4,2,4,2,16 27 DATA 20,16,20,18,16,15 29 REM MACHINE CODE (DOUBLE-CHECK!) 30 DATA 104,104,104,133,203,104,104 31 DATA 133,205,104,104,133,207,133 32 DATA 208,169,0,133,206,141,14,212 33 DATA 141,14,210,141,0,212,141,8 34 DATA 210,133,204,169,3,141,15,210 35 DATA 169,148,141,26,208,198,208 36 DATA 240,10,162,5,202,208,253,157 37 DATA 30,208,240,23,165,207,133,208 38 DATA 164,206,185,0,6,9,16,141,1 39 DATA 210,200,196,203,144,2,160,0 40 DATA 132,206,198,204,208,215,198 41 DATA 205,208,211,169,255,141,14 42 DATA 212,141,14,210,96 44 DIM QQQ$(1),QQQ(17) 45 RESTORE 29 46 FOR QQL=ADR(QQQ$)+1 TO ADR(QQQ$)+97 47 READ QQB 48 POKE QQL,QQB 49 NEXT QQL 50 RETURN
Leer el siguiente artículo que es forma de onda personalizada y revisada.
Publicado en revista Softline Volumen 2 de Mayo y Junio del 1983, páginas 18 al 20.