viernes, 16 de marzo de 2012

Algorithmic Compositions con AY

Hace un tiempo descubrí a través de neuroflip, las Algorithmic Compositions mediante un post del blog de Countercomplex. Se trata de melodías generadas mediante un algoritmo informático. El tema es bastante amplio ya que hay muchas formas de generar este tipo de música, como modelos matemáticos, sistemas basados en el conocimiento, modelos evolutivos, sistemas híbridos, etc.

En el caso del artículo de Computercomplex, se trata de una formula matemática y el código esta reducido a una sola linea. Entrando en un poco más de detalle, la formula proporciona un valor de frecuencia en base a un valor lineal (t) y se reproduce en el instante. Esto produce resultados bastante curiosos.

Cuando lo vi, pensé en intentar adaptarlo para hacerlas funcionar en un MSX con el chip AY, pero me olvide del tema, hasta principios de este año. He utilizado C (SDCC), y debido a la diferencia de velocidad de ejecución, no suenan igual, pero algunas se pueden adaptar para que suene algo con forma que no sea muy ruidoso... ;) Seguramente programado en assembler se ganaría velocidad y se podría conseguir resultados más interesantes...

El código es el siguiente (Contiene dos formulas. Una esta comentada):
/* ============================================================ */
/* sound_01.c */
/* by 2012 aorante */
/* Algorithmic symphonies */
/* ============================================================ */
// http://countercomplex.blogspot.com/2011/10/algorithmic-symphonies-from-one-line-of.html


__sfr __at 0xA8 g_slotPort;

#define HALT __asm halt __endasm

#define BASE5 0x1800

typedef enum {false = 0, true = 1} boolean;

// unsigned integer
typedef unsigned int uint;

// unsigned char
typedef unsigned char byte;

byte sound_get(byte reg);
void sound_set(byte reg, byte val);
void setChannel(byte NumChannel, boolean isTone, boolean isNoise);

void vpoke(uint address, byte value);
void vprint(byte posx, byte posy, char* text);

void main(void) {
__asm
di
ld sp, (#0xFC4A)
ei
__endasm;

g_slotPort = (g_slotPort & 0xCF) | ((g_slotPort & 0x0C) << 2); start(); } void start() { uint t; uint freq; sound_set(8,15); setChannel(0,true,false); vprint(4,15,"Algorithmic Symphonies 1"); for(t=0;t<65535;t++) //65536 { //freq=t*(t>>11&t>>8&123&t>>3); //by tejeez
freq=(t*(t>>11&t>>8&123&t>>3))>>6; //01

//freq=(t*(t>>5|t>>8))>>(t>>16); // by tejeez
//freq=((t*(t>>12&t>>6))>>(t>>16))>>4; //02

sound_set(0,freq & 0xFF);
sound_set(1,(freq & 0xFF00)/255);
}

sound_set(8,0);
vprint(3,17,"Press any key to continue...");
pressKey();

CHKRAM();
}


void pressKey()
{
__asm
call #0x009F ;CHGET
__endasm;
}

void CHKRAM()
{
__asm
call 0x0000
__endasm;
}

// activa tono y ruido de uno de los tres canales del PSG
void setChannel(byte NumChannel, boolean isTone, boolean isNoise)
{
byte newValue;

newValue = sound_get(7);

if(NumChannel==0)
{
if(isTone==true){newValue&=254;}else{newValue|=1;}
if(isNoise==true){newValue&=247;}else{newValue|=8;}
}
if(NumChannel==1)
{
if(isTone==true){newValue&=253;}else{newValue|=2;}
if(isNoise==true){newValue&=239;}else{newValue|=16;}
}
if(NumChannel==2)
{
if(isTone==true){newValue&=251;}else{newValue|=4;}
if(isNoise==true){newValue&=223;}else{newValue|=32;}
}
sound_set(7,newValue);
}


void sound_set(byte reg, byte val)
{
reg;
val;
__asm
ld a, 4(ix)
ld e, 5(ix)
call 0x0093
__endasm;
}

byte sound_get(byte reg)
{
reg;
__asm
ld A,4(ix)
call 0x0096
ld L,A
__endasm;
}

void vprint(byte posx, byte posy, char* text)
{
uint address = BASE5 + (posy * 32) + posx; // calcula la posicion en la VRAM
while(*(text)) vpoke(address++,*(text++));
}

void vpoke(uint address, byte value)
{
address;
value;
__asm
ld l,4(ix)
ld h,5(ix)
ld a,6(ix)
call 0x004D
__endasm;
}

y aquí podeis escucharlas:





El tema da para mucha experimentación. Se podría aprovechar el resto de canales, incluido el ruido.

Nota: Las formulas utilizadas son adaptaciones de las creadas por tejeez.

1 comentario:

  1. conocia esas composiciones algoritmicas, pero como friki del AY esto me ha encantado, en especial el segundo, se saca buenos sonidos

    ResponderEliminar