Generador de ruido del YM2151

El ruido que oímos en los juegos, normalmente usado para simular explosiones, golpes, etc. es generado de forma aleatoria en el interior del chip. ¿Aleatoria de verdad? Bueno, aunque los procesadores modernos sí suelen llevar un verdadero generador de números aleatorios basado en propiedades físicas de los circuitos, en el pasado y en muchas aplicaciones modernas se usa un tipo de circuito llamado registro de desplazamiento con realimentación lineal, LFSR por sus siglas en inglés (wikipedia).

En el código fuente del emulador del MAME (ym2151.c) encontramos la siguiente tabla para emular el ruido:


/*
Noise LFO waveform.
Here are just 256 samples out of much longer data.
It does NOT repeat every 256 samples on real chip and I wasnt able to find
the point where it repeats (even in strings as long as 131072 samples).
I only put it here because its better than nothing and perhaps
someone might be able to figure out the real algorithm.
Note that (due to the way the LFO output is calculated) it is quite
possible that two values: 0x80 and 0x00 might be wrong in this table.
To be exact:
some 0x80 could be 0x81 as well as some 0x00 could be 0x01.
*/
static UINT8 lfo_noise_waveform[256] = {
0xFF,0xEE,0xD3,0x80,0x58,0xDA,0x7F,0x94,0x9E,0xE3,0xFA,0x00,0x4D,0xFA,0xFF,0x6A,
0x7A,0xDE,0x49,0xF6,0x00,0x33,0xBB,0x63,0x91,0x60,0x51,0xFF,0x00,0xD8,0x7F,0xDE,
0xDC,0x73,0x21,0x85,0xB2,0x9C,0x5D,0x24,0xCD,0x91,0x9E,0x76,0x7F,0x20,0xFB,0xF3,
0x00,0xA6,0x3E,0x42,0x27,0x69,0xAE,0x33,0x45,0x44,0x11,0x41,0x72,0x73,0xDF,0xA2,
0x32,0xBD,0x7E,0xA8,0x13,0xEB,0xD3,0x15,0xDD,0xFB,0xC9,0x9D,0x61,0x2F,0xBE,0x9D,
0x23,0x65,0x51,0x6A,0x84,0xF9,0xC9,0xD7,0x23,0xBF,0x65,0x19,0xDC,0x03,0xF3,0x24,
0x33,0xB6,0x1E,0x57,0x5C,0xAC,0x25,0x89,0x4D,0xC5,0x9C,0x99,0x15,0x07,0xCF,0xBA,
0xC5,0x9B,0x15,0x4D,0x8D,0x2A,0x1E,0x1F,0xEA,0x2B,0x2F,0x64,0xA9,0x50,0x3D,0xAB,
0x50,0x77,0xE9,0xC0,0xAC,0x6D,0x3F,0xCA,0xCF,0x71,0x7D,0x80,0xA6,0xFD,0xFF,0xB5,
0xBD,0x6F,0x24,0x7B,0x00,0x99,0x5D,0xB1,0x48,0xB0,0x28,0x7F,0x80,0xEC,0xBF,0x6F,
0x6E,0x39,0x90,0x42,0xD9,0x4E,0x2E,0x12,0x66,0xC8,0xCF,0x3B,0x3F,0x10,0x7D,0x79,
0x00,0xD3,0x1F,0x21,0x93,0x34,0xD7,0x19,0x22,0xA2,0x08,0x20,0xB9,0xB9,0xEF,0x51,
0x99,0xDE,0xBF,0xD4,0x09,0x75,0xE9,0x8A,0xEE,0xFD,0xE4,0x4E,0x30,0x17,0xDF,0xCE,
0x11,0xB2,0x28,0x35,0xC2,0x7C,0x64,0xEB,0x91,0x5F,0x32,0x0C,0x6E,0x00,0xF9,0x92,
0x19,0xDB,0x8F,0xAB,0xAE,0xD6,0x12,0xC4,0x26,0x62,0xCE,0xCC,0x0A,0x03,0xE7,0xDD,
0xE2,0x4D,0x8A,0xA6,0x46,0x95,0x0F,0x8F,0xF5,0x15,0x97,0x32,0xD4,0x28,0x1E,0x55
};

Jarek Burczynski, el autor del emulador del YM2151 usado en MAME y casi en cualquier otro sitio, habla sobre cómo estas medidas de la salida del YM2151 no son periódicas, incluso después de más de cien mil muestras. También dice que algunos valores podrían estar mal debido a la forma de extraer los datos y su relación con el oscilador de baja frecuencia del chip (el LFO).

Asumiendo que estos valores debían de provenir de un LFSR y que lo más lógico era tener un LFSR por cada bit, apliqué el algoritmo de Berlekamp-Massey (wikipedia) para obtener ese supuesto registro de desplazamiento. Y este fue el resultado:

 Para todos los bits, salvo el 0 y el 4, de la secuencia de Jarek B. existe un LFSR de orden 19 y realimentación en las etapas 0, 1, 14, 15, 17 y 18.

Así que los bits que no se extrajeron bien en algunos casos fueron el 0 y el 4 y no el 0 y el 8 como pensaba Jarek. Fijaos que es la misma secuencia pseudoaleatoria para todos los bits de la palabra de ruido pero como cada LFSR está iniciado en un punto distinto de la secuencia, no van a coincidir nunca. La secuencia completa de cada bit tiene una longitud de 2^18, mucho mayor que los cien mil valores que Jarek tomó del chip. Además para ver una repetición tiene que coincidir que todas las secuencias se estén repitiendo. No voy a hacer el cálculo, pero el periodo de la secuencia es mucho mayor que 2^18.

Con estos datos ya es posible usar el mismo circuito que el original para producir el mismo ruido. Esto se puede aplicar a corregir el fichero ym2151.c de MAME o a seguir escribiendo el clón en verilog, que es lo que me ocupa a mí.

En la próxima entrada escribiré los valores con los que hay que iniciar cada LFSR para obtener la secuencia de ruido.

Anuncios

5 comentarios

  1. ¿Hablaste con los desarroladores de MAME sobre esto? Quizás podría ser beneficioso para ambos…

    1. Sí, se pusieron en contacto conmigo. Están al tanto de estos progresos. Gracias.

  2. Hola, he descubierto este blog por que buscaba el modo de obtener los patches de sonido de los juegos que usaban el YM2151. Tengo PX7 para Reason, PX7 es un emulador del DX7 y puedo correr archivos sysex. ¿Sabes si existe algún modo de extraer estos patches de los archivos vgz o de las roms de mame de las bandas sonoras que utilizaban este chip?, por ejemplo la del NBA JAM.
    Gracias, muy interesante el blog, ¡me encanta el sonido FM!.

    1. Se puede hacer. Yo he sacado alguno para hacer pruebas. Pero el proceso no es tan sencillo como pulsar una tecla. Creo que es un buen tema para una entrada del blog. A ver si este fin de semana la escribo…

      1. Pues me encantaría leerla, existe una web desde donde descargar los archivos vgz (bandas sonoras de videojuegos arcade) y también existen algunos conversores pero hasta el momento no he podido extraer los patches de estas bandas sonoras.
        No he probado a extraer las bandas sonoras desde los archivos mame, no tengo idea de eso.
        Estaré esperando leer ese artículo a ver si me puede ayudar.
        ¡Gracias!.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: