El sonido de la música
De Manual online Amstrad CPC6128
De todas las instrucciones del CPC6128, es posible que las de sonido y envolventes le parezcan las más imponentes a primera vista. Y sin embargo, con un poco de práctica, muy pronto podrá programar ruidos de diversos tipos e incluso melodías con armonía.
Empecemos por analizar las cuatro primeras partes de la instrucción SOUND, que son las siguientes: situación de canales, periodo de tono, duración de la nota y volumen. Lo primero que hay que saber es en qué margen de valores puede estar cada uno de estos parámetros.
Aplazaremos el primero de momento porque es el más complicado. El segundo, periodo de tono, puede tener cualquier valor entero comprendido entre 0 y 4095. Sin embargo sólo algunos de estos valores producen notas reconocibles: son los que están relacionados en la parte 5 del capítulo 'Para su referencia...'. Por ejemplo, el número 239 produce la nota DO media; el 253 produce la nota SI inmediatamente anterior; los valores 240 a 252 producen cada uno un tono diferente, pero ninguno de ellos corresponde a la escala del piano. Si el parámetro es 0, no se produce ningún tono; esto es útil cuando se está generando ruido.
El tercer parámetro de la orden SOUND especifica la duración de la nota en unidades de centésimas de segundo. Su valor puede estar normalmente entre 1 y 32767. Si es 0, la duración queda controlada por la 'envolvente' (de la que hablaremos más adelante). Si el parámetro es negativo, su valor absoluto indica cuántas veces se va a repetir la envolvente; por ejemplo, –3 significa 'repetir la envolvente tres veces'.
El cuarto parámetro especifica el volumen. Puede valer entre 0 y 15; el valor implícito es 12, que es el que el ordenador supone si no se especifica otra cosa. En los sonidos sencillos que hemos conocido hasta ahora, el volumen ha permanecido constante durante el tiempo en que ha sonado cada nota. Sin embargo, cuando se utiliza una 'envolvente de volumen' para hacer que éste deje de ser constante, el parámetro 'volumen' de SOUND se considera como volumen inicial de la nota.
Bueno, vamos con el parámetro de situación de anales. Quizá sepa ya el lector que el significado de este parámetro depende del valor de sus bits; para entenderlo necesitará saber algo acerca de los números binarios (parte 1 de este capítulo).
El sonido se puede generar en tres canales distintos. Si el ordenador está conectado a un amplificador estereofónico, un canal será el derecho, otro el izquierdo y otro común a ambos o central. Para especificar en qué canal o canales debe sonar una nota se utilizan los siguientes números:
1 canal A 2 canal B 4 canal C
Para enviar el sonido a varios canales, se suman los números correspondientes. Por ejemplo, para que la nota suene en los canales A y C, el parámetro debe ser 1+4=5.
SOUND 5,284
Se preguntará el lector por qué el número del canal C es 4, y no 3. Observe que estos tres números son potencias de 2(1=2^0, 2=2^1, 4=2^2) y se combinan para dar un número binario. Si imaginamos un número binario de tres dígitos, cada uno de ellos se puede utilizar para indicar si el canal correspondiente debe estar conectado o desconectado. En el ejemplo anterior, 5 en decimal es equivalente a 1*4+0*2+1*1, es decir, 101 en binario. Si a los dígitos de este número binario les ponemos las etiquetas C, B y A, tenemos
C B A 1 0 1
de forma que C y A están conectados, mientras que B está desconectado. Si quisiéramos que la nota sonase en los canales A y B, el número tendría que ser
C B A 0 1 1
En decimal: 0*4+1*2+1*1=3. La orden SOUND sería
SOUND 3,142
Naturalmente, este número tiene que coincidir con el que se obtendría sumando los valores correspondientes a los dos canales: 1+2=3 (recuerde que A=1, B=2, C=4).
Si después de todo no ha entendido cómo funciona esto en binario, no se preocupe. Le basta con saber que las combinaciones de canales se programan sumando los números de selección de los canales deseados.
Lamentablemente (o afortunadamente, según cómo se mire), todavía podemos sumar otros números a este parámetro. Así, los números 8, 16 y 32 especifican que el sonido debe sincronizarse con otro canal (A, B o C, respectivamente). Ahora hace falta saber qué es eso de 'sincronizar con un canal'. Pues bien, los sonidos que hemos generado hasta ahora han ido directamente al canal especificado. Escriba lo siguiente:
SOUND 1,142,2000 SOUND 1,90,200
A menos que sea usted un mecanógrafo muy lento, habrá tenido tiempo de escribir la segunda orden antes de que se extinguiera el primer sonido. Esto ocurre porque el sistema de sonido puede guardar hasta cinco órdenes en cada una de las colas de los tres canales. Si queremos que suene una nota por el canal A y luego dos notas simultáneamente en los canales A y B, necesitamos un forma de indicar al ordenador que no debe ejecutar la nota del canal B mientras no haya terminado la primera del A. En esto consiste la sincronización de canales. Hay dos formas de conseguirla:
SOUND 1,200,1000 SOUND 3,90,200
En este ejemplo hemos dirigido la segunda nota a A y B, y por lo tanto no puede sonar mientras no haya concluido la primera. La limitación de este método es que el sonido que se envía a varios canales tiene que ser igual en todos ellos (en este caso, ,90,200 era igual para el A que para el B). El otro método es el siguiente:
SOUND 1,200,2000 SOUND 1+16,90,200 SOUND 2+8,140,400
Aquí hemos hecho que la segunda nota de A se sincronice con el sonido de B (y que éste se sincronice con el canal A). La ventaja de este método es evidente: las notas sincronizadas pueden ser (y en este caso son) diferentes. Estos números de sincronización también son interpretables bit a bit:
8=2^3, 16=2^4, 32=2^5
Así, el número de situación de canales se puede considerar como número binario cuyos dígitos tienen el siguiente significado:
Sincr. con Sincr. con Sincr. con Sonar en Sonar en Sonar en
C B A C B A
Sumar 32 Sumar 16 Sumar 8 Sumar 4 Sumar 2 Sumar 1
Por ejemplo, para hacer sonar una nota en el canal C sincronizado con el A:
0 0 1 1 0 0
0 0 1 1 0 0 Éste es el número binario 1100, equivalente a 8+4 en decimal.
Así pues, el número de situación de canales 12 ordena a la máquina que haga sonar una nota en el canal C y que espere por una nota que debe sonar en el canal A y que ha sido marcada para sincronizarla con el C.
Si ahora sumamos 64 (=2^6) al parámetro, estamos indicando que la nota debe ser retenida. Esto significa que no va a sonar mientras no la liberemos con la orden RELEASE.
Finalmente, si sumamos 128 (=2^7), borramos la cola de sonido del canal especificado.
Por ejemplo, si hemos ordenado un sonido que va a durar un buen rato, podemos anularlo borrando la cola del canal correspondiente:
SOUND 1,248,30000
(esta nota dura 5 minutos)
SOUND 1+128,0
(pero esta la detiene)
Cuando se esté en modo directo, la forma más rápida de interrumpir un sonido es pulsar [DEL] al principio de la línea; el pitido que así se produce borra todas las colas de sonido.
Ahora que ya sabemos enviar sonido a cualquier combinación de canales (con sincronización, si es necesario), vamos a intentar producir algo más agradable que los molestos pitidos que produce una orden SOUND en esta forma sencilla. Lo haremos dotando al sonido de una envolvente: una gráfica que define cómo evoluciona la intensidad del sonido a lo largo del tiempo. Las notas producidas por los instrumentos musicales tienen una fase inicial de ataque en la que el volumen sube muy deprisa; después se mantiene a un nivel algo inferior hasta que finalmente decae gradualmente a cero. En el ordenador se puede dar una envolvente de este tipo a las notas producidas por la orden SOUND. La instrucción con la que se programa la envolvente es ENV. Veamos un ejemplo sencillo:
ENV 1,5,3,4,5,-3,8 SOUND 1,142,0,0,1
La instrucción ENV se debe ejecutar antes que la SOUND que la utiliza. Para invocar una envolvente en una instrucción SOUND se pone como quinto parámetro de éste el número de referencia de la envolvente, en este caso el 1, que es el número con que se la creó en la instrucción ENV. Los parámetros de ENV describen tanto la duración como el volumen de la nota, de modo que en SOUND podemos poner 0 en lugar de los datos de duración y volumen. La envolvente del ejemplo anterior hace que la nota crezca en 5 etapas, en cada una de las cuales el volumen aumenta en 3 unidades y cuya duración es de 4 centésimas de segundo. Después se especifica que el volumen debe decaer en 5 etapas, -3 unidades en cada una, siendo la duración de cada etapa 8 centésimas de segundo. Es decir, el primer parámetro de ENV es el número de referencia de la envolvente y va seguido por grupos de tres números. Dentro de cada grupo, el primer parámetro es el número de escalones de variación del volumen; el segundo, la amplitud de esos escalones; y el tercero, su duración. La duración total de cada sección será igual al producto del primer parámetro (número de escalones) por el tercero (duración de cada escalón). El aumento o disminución total del volumen es igual al producto del primer parámetro por el segundo (variación del volumen por escalón). La duración total de una envolvente es la suma de las correspondientes a las secciones que la integran.
En el ejemplo anterior, SOUND fijaba en 0 el volumen inicial de la nota. Pero esto no tiene que ser necesariamente así. En el siguiente ejemplo el volumen decrece desde el valor inicial 15 y luego vuelve a subir:
ENV 2,5,-2,1,20,0,1,10,1,1 SOUND 1,142,0,15,2
El número de esta envolvente es el 2. Consta de tres secciones. En la primera el volumen se reduce en 5 escalones de -2; es decir, varía a través de 5 etapas y en cada una se reduce en 2 unidades. La duración de cada etapa es de 1 centésima de segundo. La segunda sección tiene 20 etapas en las que no varía el volumen (0) y cada una de las cuales dura 1 centésima de segundo. Finalmente, la tercera sección consta de 10 etapas, con un incremento de volumen de 1 unidad y duración de 1 centésima de segundo cada una.
La instrucción SOUND especifica un volumen inicial de 15; al final de la primera sección ha decrecido hasta 5; se mantiene a ese nivel durante 20 centésimas de segundo y luego vuelve a crecer hasta alcanzar el nivel 15. Para mejor visualizar y diseñar la forma de las envolventes conviene dibujarlas en un papel milimetrado y leer en él los valores de los parámetros requeridos. En las dos figuras siguientes mostramos las dos envolventes definidas hasta ahora:
El máximo número de secciones que se puede incluir en una envolvente es 5; como cada sección requiere 3 parámetros, la instrucción ENV puede llegar a tener 16 parámetros en total, contando el primero, que indica cuál de las 15 envolventes posibles se está definiendo. Podemos imaginar los números de volumen como dispuestos en círculo; si vamos subiendo de nivel y sobrepasamos el 15, volvemos al 0; análogamente, si intentamos descender por debajo del 0, volvemos al 15. Por ejemplo, en
ENV 3,9,5,20 SOUND 1,142,0,0,3
la envolvente consta de una sola sección de 9 etapas, cada una de las cuales incrementa el volumen en 5 unidades y dura 20 centésimas de segundo. Al terminar la tercera etapa, el volumen ha subido de 0 a 15; en la cuarta etapa volverá a 4; en la quinta a 9, etc. El proceso está ilustrado en la siguiente figura:
El margen de valores para el número de escalones es de 0 a 127. En cada uno el valor puede variar entre -128 y +127 (los valores negativos representan disminución). La duración de cada escalón puede ser de entre 0 y 255 (centésimas de segundo). Ya sabemos cómo variar el volumen de una nota. Ahora podemos estudiar cómo se define la variación de su tono con el tiempo para producir efectos tales como el ‘vibrato'.
El método es muy parecido al de las envolventes de volumen. Las envolventes de tono se definen con la instrucción ENT. Por ejemplo:
ENT 1,5,1,1,5,-1,1 SOUND 1,142,10,15,,1
Las envolventes de tono se invocan con la instrucción SOUND poniendo en ésta como sexto parámetro el número de referencia de la envolvente. La instrucción ENT tiene que ser ejecutada antes que la SOUND que la utiliza.
Este primer ejemplo de ENT define la envolvente de tono número 1. La primera sección consta de 5 etapas; en cada una el periodo de tono crece en 1 unidad; cada una dura 1 centésima de segundo. La segunda sección consta de 5 etapas; la variación del periodo de tono en cada una de ellas es -1 (descenso); la duración de cada etapa es de 1 centésima de segundo. La duración total es, pues, 5+5 =10 centésimas de segundo. Obsérvese que esta duración ha sido especificada en SOUND, ya que la duración de la envolvente de tono no determina la duración de la nota (mientras que sí lo hace la envolvente de volumen). Si la duración especificada en SOUND es menor que la de la envolvente, el final de ésta se perderá. Si es mayor, el final de la nota se ejecutará a tono constante. Esto último es también aplicable a las envolventes de volumen.
(Nótese la ausencia del número de envolvente de volumen en la última instrucción SOUND, debida a que aún no hemos definido una envolvente de volumen para este sonido.)
Las envolventes de tono normalmente duran menos que la nota. Se puede hacer que la envolvente se repita mientras la nota está sonando. Para ello se especifica un número de envolvente negativo, cuyo valor absoluto se cita en la instrucción SOUND:
ENT -5,4,1,1,4,-1,1 SOUND 1,142,100,12,,5
Esta repetición de la envolvente produce el efecto 'vibrato'. Cuando se diseñan envolventes de tono, es conveniente que el tono varíe simétricamente con respecto al valor inicial, de forma que al repetir la envolvente el tono no se desvíe demasiado con respecto al valor central. Pruebe el siguiente sonido:
ENT -6,3,1,1 SOUND 1,142,90,12,,6
Habrá observado que la frecuencia ha disminuido drásticamente. Esto ha ocurrido porque la envolvente impone un aumento del periodo de tono de 3 unidades y se repite 30 veces (90/3). No obstante, ese efecto se puede aprovechar para imitar trinos y sirenas:
ENT -7,20,1,1,20,-1,1 SOUND 1, 100, 400, 12,,7
ENT -8,60,-1,1,60,1,1 SOUND 1,100,480,12,,8
Se pueden definir hasta 15 envolventes de tono, con números de referencia del 1 al 15; los números negativos indican que la envolvente se repite. Para cada sección, el número de escalones puede estar entre 0 y 239. La variación del periodo de tono en cada escalón puede ser de entre -128 y +127. La duración de cada escalón puede ser de entre 0 y 255 (centésimas de segundo). Cada envolvente puede tener hasta 5 secciones.
El último parámetro que se puede incluir en la instrucción SOUND, el séptimo, caracteriza el nivel de ruido que se añade al sonido. Obsérvese que sólo hay un canal de ruido y que, por consiguiente, cada vez que se especifica un nivel de ruido se anula la anterior especificación.
El ruido se puede mezclar con un tono, pero también se lo puede programar por separado, para lo cual se debe poner un 0 como periodo de tono en SOUND. Esto es útil para imitar ruidos de percusión:
ENT -3,2,1,1,2,-1,1 ENV 9,15,1,1,15,-1,1 FOR a=1 TO 10:SOUND 1,4000,0,0,9,3,15:NEXT
Un ruido como éste puede servir de base para imitar el de una locomotora. Obsérvese que hemos combinado los dos tipos de envolvente y el ruido. En SOUND hemos puesto 0 para los parámetros de duración y de volumen, por lo que estas características quedan controladas por las envolventes de volumen.
Como ya estamos en condiciones de utilizar SOUND, ENV y ENT a plena potencia, vamos a estudiar algunas otras órdenes y funciones.
Como el lector recordará, al describir el primer parámetro de SOUND dijimos que si le sumábamos el número 64 el sonido quedaba 'retenido' en la cola, y que no sonaría mientras no lo liberásemos. La forma de liberarlo es ejecutar la orden RELEASE. Esta palabra va seguida de un número cuyos bits determinan a qué canales afecta la orden:
4 significa canal C 2 significa canal B 1 significa canal A
Los canales se combinan sumando los números correspondientes. Así, para liberar el sonido de los tres canales la orden que se requiere es:
RELEASE 7
donde 7=1+2+4. Si no hay sonido retenido en ningún canal, la orden no tiene efecto. Pruebe lo siguiente:
SOUND 1+64,90 SOUND 2+64,140 SOUND 4+64,215 RELEASE 3:FOR t=1 TO 1000:NEXT:RELEASE 4
No se produce ningún sonido mientras no se ejecuta la primera orden RELEASE, la cual libera los sonidos de los canales A y B. Después de una pausa, la segunda orden RELEASE libera el canal C.
Hay otro método para sincronizar sonidos. Cuando se retiene un sonido sumando 64 a su número de situación de canal, no sólo queda él retenido, sino todos los que se envíen a continuación a ese mismo canal. Si se envían más de cuatro sonidos a una cola que está retenida, la máquina queda bloqueada hasta que se libere la cola (posiblemente al ejecutarse una subrutina invocada por AFTER o EVERY). Ésta no es una buena forma de gestionar los sonidos, ya que la máquina se detendrá cada vez que se llene una cola. Lo mismo ocurre si se ejecutan varias órdenes SOUND seguidas. Pruebe este programa:
10 FOR a=1 TO 8 20 SOUND 1,100*a,200 30 NEXT 40 PRINT"hola" run
El texto no aparece en la pantalla inmediatamente, sino al cabo de tres segundos. Esto ocurre porque el programa no puede llegar a la línea 40 mientras no haya espacio libre en la cola para almacenar todos los sonidos.
BASIC dispone de un mecanismo de interrupción, similar al que se utiliza en AFTER, EVERY y ON BREAK GOSUB, mediante el cual se puede hacer que se ejecute una subrutina cada vez que queda espacio libre en una cola especificada:
10 a=0 20 ON SQ(1) GOSUB 1000 30 PRINT a; 40 GOTO 30 1000 a=a+10 1010 SOUND 1,a,200 1020 IF a<200 THEN ON SQ(1) GOSUB 1000 1030 RETURN
Observe que el programa no se detiene. La instrucción SOUND no se ejecuta mientras no hay espacio libre en la cola del canal A (1), hecho que detecta la orden ON SQ( ) GOSUB de la línea 20. Esta orden inicializa un mecanismo de interrupción que ejecuta la subrutina cada vez que queda un hueco libre en la cola especificada. El mecanismo tiene que ser reinicializado cada vez que se ejecuta la subrutina (línea 1020). En este ejemplo, la reinicialización sólo se produce si a es menor que 200.
En un programa que lleve a cabo acciones relativamente lentas (por ejemplo, mover objetos por la pantalla), se puede poner música de fondo programando una subrutina que ejecute una nota cada vez que quede un hueco libre en la cola. De esta forma se asegura que el programa no se va a detener en espera de que quede espacio en la cola. Si los valores de las notas están contenidos en listas DATA, se puede hacer que la subrutina de sonido deje de reinicializarse cuando los datos estén a punto de agotarse.
El parámetro que va entre paréntesis en la instrucción ON SQ( ) GOSUB puede ser 1, 2 o 4, dependiendo del canal cuya cola se desee examinar.
Hay una función, SQ( ), que se puede utilizar para determinar el estado de los canales de sonido. Su parámetro puede ser 1, 2 o 4. El valor generado por la función se interpreta bit a bit según la siguiente tabla:
Bit Decimal Significado 0,1,2 1 a 4 Número de huecos libres en la cola 3 8 La primera nota de la cola está marcada para sincronizar con el canal A 4 16 La primera nota de la cola está marcada para sincronizar con el canal B 5 32 La primera nota de la cola está marcada para sincronizar con el canal C 6 64 La primera nota de la cola está retenida (está a 1 el bit de retención) 7 128 En este momento está sonando una nota
Pruebe el siguiente ejemplo:
10 SOUND 2,200 20 x=SQ(2) 30 PRINT BIN$(x) run
La línea 30 escribe el número binario 10000100. El bit 7 está a 1, lo que indica que en el canal había una nota sonando cuando se ejecutó la línea 20. Los tres dígitos menos significativos son 100; equivalen al número decimal 4, y esto quiere decir que había cuatro espacios libres en la cola. Esta función examina la situación del canal en un punto específico del programa; en cambio, ON SQ( ) GOSUB examina la cola, y reacciona en consecuencia, en un punto indeterminado.
Hasta ahora todos los ejemplos han consistido en hacer sonar una o dos notas. Si se va a ejecutar un grupo de notas independientes, por ejemplo las de una melodía, sus características se pueden guardar en líneas DATA, para luego leerlas con READ e introducirlas en SOUND:
10 FOR octava=-1 TO 2 20 FOR x=1 TO 7:REM notas por octava 30 READ nota 40 SOUND 1,nota/2foctava 50 NEXT 60 RESTORE 70 NEXT 80 DATA 426,379,358,319,284,253,239 run
El ejemplo final de esta sección se basa en este concepto. En los canales A y B se hace sonar una melodía con ritmo, utilizando la sincronización. Este ejemplo muestra cómo utilizar las listas DATA para incluir información sobre nota, octava, duración y sincronización:
10 REM la linea 190 da la melodia en clave de agudos 20 REM la linea 200 da la melodia en clave de graves 30 DIM escala%(12):FOR x%=1 TO 12:READ escala%(x%):NEXT 40 canal1%=1:READ canal1$:canal2%=2:READ canal2$ 50 CLS 60 velocidad%=12 70 escala$=" a-b b c+c d-e e f+f g+g" 80 ENV 1,2,5,2,8,-1,10,10,0,15 90 ENV 2,2,7,2,12,-1,10,10,0,15 100 ENT -1,1,1,1,2,-1,1,1,1,1 110 DEF FNm$(s$,s)=MID$(s$,s,1) 120 canal1%=1:GOSUB 200 130 canal2%=1:GOSUB 380 140 IF canal1%+canal2%>0 THEN 140 150 END 160 DATA &777,&70c,&6a7,&647,&5ed,&598 170 DATA &547,&4fc,&4b4,&470,&431,&3f4 180 DATA 4cr4f4f1f1g1A1-B2C2f4g2g1A1-B6A2Crlflglflgla1-blAl-b2C2g2A2g2f1g1a2g2f6e2c2e2c2g2e2c1-B1A2g2f4e4d8c4f3f1c2d4-b2fr2-B2A2g2f6e2gr4C4-Bla1f1-b1g2c2-b4a4g4fr6A2A2-B4-B2Ar2-B2A2g2f6e2g4C4-B1A1f1-B1g2C2-B4 A4g8f. 190 DATA r4f4f8f4e4c4fr8f4e2f2e4d2e2d8c8c6e2f4g4g8e4f3f1c4dr8g4cr4e4c6f2d4c4c8fr8-e4dr8g8c4e4c6f2d4c4c8f. 200 REM enviar sonido al canal A 210 p1$=FNm$(canal1$,canal1%) 220 IF p1$<>"r" THEN r1%=0:GOTO 240 230 r1%=16:canal1%=canal1%+1:p1$=FNm$(canal1$,canal1%) 240 IF p1$="." THEN canal1%=0:RETURN ELSE l1%=VAL(p1$) 250 canal1%=canal1%+1 260 n1$=FNm$(canal1$,canal1%) 270 canal1%=canal1%+1 280 IF n1$="+" OR n1$="-" THEN 350 290 n1$=" "+n1$ 300 nd1%=(1+INSTR(escala$,LOWER$(n1$)))/2 310 IF ASC(RIGHT$(n1$,1))>96 THEN o1%=8 ELSE o1%=16 320 SOUND 1+r1%,escala%(nd1%)/o1%,velocidad%*l1%,0,1,1 330 ON SQ(1) GOSUB 200 340 RETURN 350 n1$=n1$+FNm$(canal1$,canal1%) 360 canal1%=canal1%+1 370 GOTO 300 380 REM enviar sonido al canal B 390 p2$=FNm$(canal2$,canal2%) 400 IF p2$<>"r" THEN r2%=0:GOTO 420 410 r2%=8:canal2%=canal2%+1:p2$=FNm$(canal2$,canal2%) 420 IF p2$="." THEN canal2%=0:RETURN ELSE l2%=VAL(p2$) 430 canal2%=canal2%+1 440 n2$=FNm$(canal2$,canal2%) 450 canal2%=canal2%+1 460 IF n2$="+" OR n2$="-" THEN 530 470 n2$=" "+n2$ 480 nd2%=(1+INSTR(escala$,LOWER$(n2$)))/2 490 IF ASC(RIGHT$(n2$,1))>96 THEN o2%=4 ELSE o2%=8 500 SOUND 2+r2%,escala%(nd2%)/o2%,velocidad%*l2%,0,1,2 510 ON SQ(2) GOSUB 380 520 RETURN 530 n2$=n2$+FNm$(canal2$,canal2%) 540 canal2%=canal2%+1 550 GOTO 480 run
@@ Pendiente de incluir imágenes
(Puede seguir leyendo... Dicho gráficamente)