Página 1 de 1

Sonidos en BASIC con la instrucción OUT

Publicado: Sab Nov 10, 2007 12:09 am
por Bubu
Buenas,

me gustaría saber si desde BASIC y utilizando la instrucción OUT existe algún método para realizar una nota musical o algo que se le parezca.

Publicado: Sab Nov 10, 2007 12:45 am
por radastan
El puerto 254 controla el sonido y los colores de pantalla:

BIT 0, 1, y 2 (de 0 a 7 en decimal) controlan el color del borde

BIT 3 controla la señal SAVE de cinta (8 en decimal)

BIT 4 controla el sonido (16 en decimal)

Es decir, si haces un IN 254, y si no modificas el borde de pantalla, ese IN es el valor que pone a 0 el altavoz, y si sumas 16 es el valor con el altavoz a 1.


Una prueba rápida:

10 LET a=IN 254
20 OUT 254,a+16
30 OUT 254,a
40 GO TO 20

Publicado: Sab Nov 10, 2007 12:58 am
por radastan
Ea... me ha dado por hacer el chorra... aquí tienes un simulador de timbre de la puerta:

10 LET a=IN 254
20 OUT 254,a+(16*(INKEY$="1"))
30 OUT 254,a
40 GO TO 20

Publicado: Sab Nov 10, 2007 1:00 am
por Bubu
Ese código me da

Código: Seleccionar todo

B Integer out of range 20:1


porque sumar 16 a un valor mayor que 239 produce un valor mayor que 255, y claro, peta. La línea 20 sería más bien:

Código: Seleccionar todo

OUT 254, a OR 16


para así levantar siempre el BIT 4 del puerto 0xFE, pero lo que sigo sin pillar es, si quiero emitir un DO, p.ej. ¿se puede usar este puerto?

Publicado: Sab Nov 10, 2007 2:02 am
por mcleod_ideafix
Sí, puedes emitir un DO... siempre que no te importe que sea en escala de infrasonidos :D
Es que el BASIC no tiene velocidad como para emitir una onda de audio de mucha frecuencia... como mucho llegarás a unos 100Hz.
Lo más rápido (y por tanto la frecuencia más alta) que puedes conseguir es:

Código: Seleccionar todo

10 OUT 254,0: OUT 254,255: GO TO 10

Otra cosa es usar OUT con los puertos del AY-3192 de los modelos 128K. AHí sí que podrías emitir más variedad de sonidos desde BASIC.

Publicado: Sab Nov 10, 2007 2:07 am
por mcleod_ideafix
Bubu escribió:

Código: Seleccionar todo

OUT 254, a OR 16


OJO! Ese código no hace lo que piensas. a OR 16 no tiene el mismo significado que la expresión en C: a | 16 (operador de bit)
En el BASIC del Spectrum, esa expresión vale siempre 1 (verdadero). Es más bien equivalente a la expresión C: a || 16

Publicado: Sab Nov 10, 2007 2:07 am
por Bubu
OK, entóns me olvido de hacer música con OUT en BASIC, si acaso para algún "efecto especial" tipo explosión o golpe.

Publicado: Sab Nov 10, 2007 2:33 am
por mcleod_ideafix
Bubu escribió:OK, entóns me olvido de hacer música con OUT en BASIC, si acaso para algún "efecto especial" tipo explosión o golpe.

A esas frecuencias, ¿un efecto especial?..... sí, un pedo :D

Publicado: Sab Nov 10, 2007 2:37 am
por Bubu
Bueeeeno, pero sería un cuesco de los de fabada, porque vaya lo que estoy escuchando con las pruebas del OUT, jiji.

Publicado: Sab Nov 10, 2007 9:55 am
por radastan
Bubu escribió:Ese código me da

Código: Seleccionar todo

B Integer out of range 20:1


porque sumar 16 a un valor mayor que 239 produce un valor mayor que 255, y claro, peta. La línea 20 sería más bien:

Código: Seleccionar todo

OUT 254, a OR 16


para así levantar siempre el BIT 4 del puerto 0xFE, pero lo que sigo sin pillar es, si quiero emitir un DO, p.ej. ¿se puede usar este puerto?


El código funciona sin problemas, a menos que cambies los colores del borde de pantalla DESPUES del IN 254. Precisamente hago un IN para ver como está el puerto y sólo sumar 16, que es el puñetero bit de audio. Sólo podrías tener un valor de 239 si el BIT 4 está activado, piensa.

Publicado: Sab Nov 10, 2007 9:57 am
por radastan
mcleod_ideafix escribió:Otra cosa es usar OUT con los puertos del AY-3192 de los modelos 128K. AHí sí que podrías emitir más variedad de sonidos desde BASIC.


¿Sabes donde se explican dichos puertos? es que es mi asignatura pendiente, manejar el sonido del 128K+ desde ensamblador (no me he metido con ello aún y ya mismo me hace falta).

Publicado: Sab Nov 10, 2007 12:08 pm
por Bubu
No entiendo. Si el puerto ya tiene el bit 4 levantado y tú le sumas 16, estarías desbordando el valor, ¿no? Habría que chequar primero si el bit 4 está a cero, ¿no?

Publicado: Sab Nov 10, 2007 12:50 pm
por na_th_an
@radastan: yo lo saqué del WOS, de donde explican los modelos de 128K. De todos modos, mira:

Código: Seleccionar todo

/*
   AY REGISTERS - To play sound, just write to 0, 1, 6, 7, 8, 11, 12, 13

    0              Channel A fine pitch            8-bit (0-255)
     1              Channel A course pitch          4-bit (0-15)
     2              Channel B fine pitch            8-bit (0-255)
    3              Channel B course pitch          4-bit (0-15)
    4              Channel C fine pitch            8-bit (0-255)
    5              Channel C course pitch          4-bit (0-15)
    6              Noise pitch                     5-bit (0-31)
    7              Mixer                           8-bit (see below)
    8              Channel A volume                4-bit (0-15, see below)
    9              Channel B volume                4-bit (0-15, see below)
   10              Channel C volume                4-bit (0-15, see below)
   11              Envelope fine duration          8-bit (0-255)
   12              Envelope course duration        8-bit (0-255)
   13              Envelope shape                  4-bit (0-15)
   14              I/O port A                      8-bit (0-255)
   15              I/O port B                      8-bit (0-255)

Bit: 7        6        5        4        3        2        1        0
   _         _
   I/O       I/O   Noise    Noise    Noise     Tone     Tone     Tone
     B        A        C        B        A        C        B        A

*/

unsigned char sound1[] = {100,50,0,0,0,0,4,216,31,0,0,10,10,9};
unsigned char sound2[] = {250,250,0,0,0,0,15,248,31,0,0,10,10,0};
unsigned char sound3[] = {10,10,0,0,0,0,29,216,31,0,0,4,4,0};
unsigned char sound4[] = {10,100,0,0,0,0,15,248,31,0,0,50,50,0};
unsigned char sound5[] = {15,1,0,0,0,0,15,248,31,0,0,50,50,0};

unsigned char *sounds[] = {sound1, sound2, sound3, sound4, sound5};
void my_play_sound (int n)
{
   sp_outp (65533, 4);
   sp_outp (49149, *(sounds[n]));
   sp_outp (65533, 5);
   sp_outp (49149, *(sounds[n] + 1));
   sp_outp (65533, 6);
   sp_outp (49149, *(sounds[n] + 6));
   sp_outp (65533, 7);
   sp_outp (49149, *(sounds[n] + 7));
   sp_outp (65533, 10);
   sp_outp (49149, *(sounds[n] + 8));
   sp_outp (65533, 11);
   sp_outp (49149, *(sounds[n] + 11));
   sp_outp (65533, 12);
   sp_outp (49149, *(sounds[n] + 12));
   sp_outp (65533, 13);
   sp_outp (49149, *(sounds[n] + 13));
}


Está en C, pero es lo mismo :D

Re:

Publicado: Lun Nov 12, 2007 10:42 pm
por radastan
na_th_an escribió:@radastan: yo lo saqué del WOS, de donde explican los modelos de 128K.

Está en C, pero es lo mismo :D


Me vale, perfecto, ahora a experimentar unos meses a ver que consigo...

Re: Sonidos en BASIC con la instrucción OUT

Publicado: Mar Nov 13, 2007 11:24 am
por na_th_an
La verdad es que es fácil. Es importante colocar los datos que quieras que suenen en los bytes que controlan cada canal, y luego programar el byte 7 que es el mixer (detallado en los comentarios bit a bit). Con eso activas el AY hasta la siguiente llamada. Usando esto es fácil construirse un reproductor símplemente secuenciando en el tiempo las modificaciones de los canales y el byte 7 (mixer).