Archive for Demoscene

ResaCON 2009

Todo surgió de esta idea:

Con lo interesantes que se ponen las conversaciones a veces cuando nos vamos de cena, ¿por qué no montamos una con y nos contamos las cosas que hacemos como $DEITY manda?

Después de un periodo de incertidumbre y de apurar un poco con las fechas (una deadline es una deadline al fin y al cabo), el pasado fin de semana tuvo lugar la ResaCON 2009: once amigos y yo, cada uno con una presentación bajo el brazo, una pantalla grande, una nevera con refrescos y algo para picar. El resultado fue espectacular: se habló de gráficos, IA, emulación, videojuegos, lenguajes de programación, robotitos, proyectos personales varios, silverlight, profiling y hasta de creación de empresas… todo ello en un ambiente familiar y distendido.

Por supuesto luego hubo tiempo para irnos de cena y de fiesta :D

En definitiva, he disfrutado de lo lindo y espero que repitamos el año que viene (¡muchas gracias a todos, moláis un gritón!) . En los próximos días subiré a algún sitio las presentaciones que me dejen subir, permanezcan en sintonía. De momento os dejo con un enlace a mi presentación de introducción a Clojure.

Comments (3)

Síntesis musical para mí (o para torpes en general :) III

3) Más ondas básicas

No solo de senos vive el hombre (salvo que nos pongamos a hacer síntesis aditiva), así que vamos a ver unas cuantas ondas más que podemos utilizar como base para construir sonidos.

  • Onda cuadrada:

    Get the Flash Player to see this player.

    Se obtiene alternando dos valores (en nuestro caso +1 y -1) con la frecuencia deseada. Expresado en código, podría ser algo como esto:

    // Generacion del i-esimo sample de una onda cuadrada 
    // de frecuencia f
    float t = i/sampling_rate; // instante i en segundos
    float periodo = 1.0f / f; // periodo de la onda en segundos
    if (fmodf(t,periodo) < periodo/2.0f)
        y[i] = 1.0f;
    else
        y[i] = -1.0f;
    

    Onda cuadrada.

    Otra posibilidad es hacer que las zonas a +1 y -1 no tengan la misma longitud (pulse width modulation)

  • Onda de diente de sierra:

    Get the Flash Player to see this player.

    En cada periodo, aumenta linealmente desde -1 a 1, cayendo bruscamente a -1 en el comienzo del siguiente periodo. Dicho en C viene a ser:

    // Sample i-esimo, frecuencia f
    float t = i/sampling_rate;
    float periodo = 1.0f / f;
    y[i] = 2.0f*(fmodf(t, periodo)/periodo)-1.0f;
    

    Onda de diente de sierra.

  • Onda triangular:

    Get the Flash Player to see this player.

    Es parecida a la anterior, pero durante la mitad del periodo crece linealmente de -1 a 1, y durante la otra mitad decrece linealmente volviendo a -1, sin discontinuidad.

    // Sample i-esimo, frecuencia f
    float t = i/sampling_rate;
    float periodo = 1.0 / f;
    float semiperiodo = periodo/2.0f;
    if (fmodf(t,periodo) < periodo/2.0f)
        y[i] = 2.0f*(fmodf(t,semiperiodo)/semiperiodo)-1.0f;
    else
        y[i] = 1.0f-2.0f*fmod(t,semiperiodo)/semiperiodo;
    

    Onda triangular.

En el programa de ejemplo de este capítulo (ahora con un 100% más de Makefile) está todo esto en forma compilable para poder probarlo fácilmente. Por cierto, ninguno de los ejemplos está optimizado porque pretenden ser lo más claros posible, si alguien tiene sugerencias sobre como implementar mejor cualquier cosa nos lo podemos pasar muy bien comentándolas :)

En fin, esto es todo por hoy. En el próximo post, cosillas sobre espectros de frecuencias y aliasing (supongo que la pereza me obligará a dejarme los filtros para dentro de dos posts :)

EDIT: A peticion de pplux, ahi van los enlaces a los posts anteriores:

Comments (4)

Síntesis musical para mí (o para torpes en general :) II

2) Senos!!!

Después del ruido del capitulo anterior, vamos a pasar a algo ligeramente más interesante: la onda senoidal. Como podéis ver si seguís el enlace a la pagina sobre la onda senoidal en la wikipedia, junto con dibujitos y explicaciones interesantes, la formula es:

y = A·sin(w·t + fase)

donde A es la amplitud de la onda (la distancia entre una cresta y un valle), w es la frecuencia en radianes/segundo y t es el tiempo. Vamos a ignorar la fase porque no nos hace falta :)

Como nos gusta trabajar con frecuencias en hercios, multiplicamos por 2·pi. Además, tenemos que t = samples generados / frecuencia de muestreo. Por lo tanto en el código tendremos algo como:

y[i] = A*sin(2*pi*frecuencia*(i/sampling_rate))

para el sample i-ésimo desde el inicio del sonido. Vamos a ver el trozo de código correspondiente (lo que falta es, básicamente, la inicialización del capítulo anterior):

void play(void *userdata, Uint8 *stream, int len)
{
    int num_samples = len / 2;
    Sint16 *dst_buf = (Sint16*) stream;
    for (int i=0; i<num_samples ; ++i)
        buffer[i] = sin(2.0*M_PI*440.0f*(i+pos)/(float)SAMPLING_RATE);
    
    // Clipping y conversion a Sint16
    for (int i=0; i<num_samples; ++i)
    {
        float v = buffer[i];
        if (v > 1.0f)
            v = 1.0f;
        else if (v< -1.0f)
            v = -1.0f;

        dst_buf[i] = (Sint16)(32767.0f*v);
    }
    pos += num_samples;

}

Detalles destacables de esta función:

  • se trabaja con un buffer de floats y se convierte a entero al final. No mola ir perdiendo precisión por el camino, sobre todo cuando hagamos cosas mas complejas
  • hay clipping a [-1.0, 1.0]. Ahora mismo es completamente innecesario porque sin() devuelve valores en ese intervalo, pero cuando empecemos a mezclar varios sonidos vendrá bien :)
  • en la llamada a sin(), el 440.0f es la frecuencia de la nota que suena (un La4), y pos es una variable global que guarda el índice del ultimo sample generado entre llamadas a play(). Es feo, pero para un ejemplo pequeño va bien.

En el próximo episodio (ahora es tarde y tengo sueño), veremos otros osciladores típicos y cosas interesantes que se pueden hacer con ellos.

EDIT: herotyc me ha enviado una versión stand-alone del ejemplo de este capítulo. ¡Muchas gracias! :)

Comments (14)

Síntesis musical para mí (o para torpes en general :)

Por petición popular (hola pplux) voy a hacer una pequeña introducción a la síntesis de audio desde el punto de vista de un coder sin experiencia previa en DSP que pretende hacer un sintetizador para intros de 4k (yo). Por supuesto, incluirá ejemplos de código. C99 y SDL for teh win.

0) Disclaimer
Esto no tiene por qué ser la forma correcta de hacer las cosas. Hasta donde yo sé funciona, pero seguro que hay muchos fallos en muchos sitios. Son bienvenidos los comentarios, tanto para corregirme los fallos como para comentar cualquier otra cosa al respecto :). Y como se suele decir en estos casos, si alguno de los ejemplos de código rompe algo o deja sordo a alguien yo no me hago responsable.

1) Haciendo ruido

En primer lugar, el clásico trozo de codigo de inicialización que todo el mundo copia y pega y nadie lee:

#include "SDL.h"

#define BUFFER_SIZE 1024    // Longitud del buffer, en samples

// Este comentario esta extraido de SDL_audio.h, porque me ha molado
/* This function is called when the audio device needs more data.
 * 'stream' is a pointer to the audio data buffer
 * 'len' is the length of that buffer in bytes.
 * Once the callback returns, the buffer will no longer be valid.
 * Stereo samples are stored in a LRLRLR ordering.
 */
void play(void *userdata, Uint8 *stream, int len)
{
    int num_samples = len / 2;
    Sint16 *buf = (Sint16*) stream;
    for (int i = 0; i<num_samples ; ++i)
        buf[i] = rand()%65535-32768;

}

int main(int argc, char **argv)
{
    SDL_AudioSpec desired;
    desired.freq     = 44100;        // Frecuencia de muestreo                             
    desired.format   = AUDIO_S16SYS; // Formato de las muestras
    desired.channels = 1;            // Numero de canales
    desired.samples  = BUFFER_SIZE;  // Tamaño del buffer en samples
                                     // (potencia de 2)
    desired.callback = play;         // Callback
    desired.userdata = NULL;         // Puntero a datos
    
    SDL_Init(SDL_INIT_AUDIO);        
    SDL_OpenAudio(&desired, NULL);
    SDL_PauseAudio(0);
    getchar();
    SDL_PauseAudio(1);
    SDL_CloseAudio();
    SDL_Quit();
}


La parte importante esta en buf[i] = rand()%65535-32768; Como hemos elegido AUDIO_S16SYS significa que utilizamos muestras de 16 bits con signo [-32768, 32767], con endianismo dependiente del sistema (como accedemos al buffer con punteros a entero de 16 bits, el endianismo no será problema). Generamos numeros aleatorios en ese rango y ya tenemos ruido blanco saliendo de nuestros altavoces.

No se pierdan el proximo episodio.

EDIT: He cambiado el titulo, de “sintesis de audio” a “sintesis musical” porque lo primero era demasiado general :)

Comments (777)

Night of the proms + Breakpoint

Por fin llegó el dia de volver a ver a Mike Oldfield en España. Habia que aprovechar la ocasión y estuve en los conciertos de Valencia y Madrid.

El primer dia en Valencia estuve en la primera fila (fotos proximamente :D), y en el concierto de Madrid me vi relegado a la grada por comprar la entrada a ultima hora. Ambos estuvieron geniales, y me parece que el año que viene iré al NOTP toque quien toque.

Ahora solo falta que sea verdad lo que dijo el señor Oldfield de venir proximamente a dar algun concierto mas largo.

En otras noticias, estoy en la breakpoint. Shash y yo hemos presentado 4k, y la compo es dentro de 1:40h. Ahora que el partycoding ya ha pasado… FIESTA! \o/

Seguiremos informando.

Comments (1)

Breakpoint!

Acabo de comprar los billetes para la Breakpoint de este año. Ya veremos que tal sale lo de viajar con Ryanair, pero por lo pronto el viaje sale hiperbarato.

De Valencia solo vamos (al menos de momento) aTMsA y yo, pero alli habrá un monton de caras conocidas, como el grupo de 10 sceners que sale de Barcelona :)

Las proximas semanas se presentan moviditas: concierto de Yann Tiersen el 1 de marzo, luego fallas, luego el Night of the Proms el 30, Breakpoint a principios de abril… :D

Comments (1)

Actualización de la web

Cambios en mi web. Que nadie se asuste, sigue conteniendo un 0% de webdospuntocerismo.

He añadido la red trip a la lista de prods, y he puesto screenshots de las intros para que la web no sea sólo un enorme bloque de texto con links. Ahora un visitante casual puede mirar los dibujitos, como se hace con los buenos libros, y ver los screenshots en orden cronológico. Me recuerda shash que tengo varias intros pendientes de portar a Linux. A ver si encuentro una forma decente de pintar texto en OpenGL sin usar chorrocientas libs externas ni dejarme miles de bytes en el intento.

Quien ya conozca las prods no encontrará nada especialmente nuevo. Los screenshots son exactamente los mismos que hay en pouet :)

Comments (1)

BCNParty 110

Este último fin de semana he estado en la BCNParty.

El jueves por la noche llegué con stage7 a Barcelona, donde shash nos recogió y nos llevó a su casa. stage7 había terminado durante el viaje su tema para la compo de streamed music, una versión de mi track jarresco para la syltia(coop 4k Bauknecht/Necrostudios) que me encanta como ha quedado :D. Como llovía nos quedamos en casa de shash haciendo cosillas de la intro y viendo grandes éxitos en YouTube.

El viernes nos levantamos tarde y llegamos a la party sobre las 16:00. Sesión de partycoding, partycomposing-con-el-vim, y por la noche descanso para degustar la super sangria of the death que yomizmo preparó. Fueron unas horas geniales en las que los miembros de TimeScratchers nos deleitaron con un montón de chistes, mientras otros traducian los chistes al inglés (como razonable éxito ;) para que los sceners extranjeros pudieran entender algo.

El sábado era el dia clave para terminar la intro, es decir, el último :D. Terminé el track como buenamente pude, a pesar de la completa falta de inspiración, y nos pusimos a sincronizarlo todo. No tuvimos demasiados problemas para conseguir el tamaño correcto, aunque hubo un momento de pánico cuando casi me cargo el sinte intentando sustituir la rutina de los ADSRs por un decay exponencial que iba mas o menos bien en mi maquina (40% de consumo aproximado de CPU, eso si :P) pero hacia sufrir demasiado al PC cuando lo pasé a windows. Todavía seguimos buscando el porqué. Resultado final: Red trip by Collapse and Necrostudios.
Entregamos la intro 15 minutos antes de las proyecciones, nos hicimos unos pintxos en el bar de enfrente del partyplace *muy* rápido y despues de ver las compos nos fuimos de fiesta toda la noche. Llegamos justo a tiempo para desayunar en la estación y despedir a stage7, que se iba a las 8:00. Después a dormir un rato, lo justo para llegar a la entrega de premios.

Al final quedamos segundos. Personalmente estoy bastante contento con la intro teniendo en cuenta la carencia de ideas en los dias previos. Ha quedado algo bastante potable y bien terminado. El nivel de las compos en general fue un poco menor de lo esperado, pero al menos ganó una demo española y escena.org vuelve a estar online ;)
En resumen, la party ha estado muy bien a pesar de la falta de prods (lástima) y me lo he pasado genial. Gracias a todos!

Comments

Inercia Demoparty 2006 (segunda parte)

Ya ha terminado la party. El viernes PpluX leyó su papel en el congreso, yo medio terminé la intro4k que había empezado y nos subimos en el autobús. Llegamos al partyplace sobre las 18:30 y Evil me dice que como el demoshow iba a ser a las 22:00, tenia hasta las 21:00 para reducir los 50 bytes que me sobraban, empaquetar la intro y subirla. Sin problemas.

Mientras tanto, hablamos con la orgo del congreso para aclarar el tema del shuttle a Lisboa el dia siguiente, que supuestamente salía a las 6:00 del sábado. Sin embargo, nos dicen que habían cambiado el autobús a esa misma tarde y que para llegar el sábado por la mañana a Lisboa tendríamos que pillar el taxi hasta Portalegre y luego un bus desde allí. Por lo menos conseguimos que nos reservaran el taxi para el dia siguiente a las 7:00.

Vuelta a la party, subo la 4k y poco después llega jeenio. Me hacía ilusión participar en la pirated demo compo y se lo propuse a jeenio y a mauge, que también estaba por allí. Jeenio grabó la música asombrosamente rápido mientres mauge y yo retocabamos los gráficos de la cafre, de Stravaganza. ps nos retrasa aun más la deadline (real sceners always deliver after the deadline :D) y conseguimos presentarla también.

En total, 2 intro4k, una intro64k, una demo, dos pirated demos y 2 wilds.

Tras el demoshow, jam session con jeenio, evil, xernobyl, otro chico que no se quien es pero que tocaba muy bien el teclado y ps cantando de vez en cuando hasta prácticamente las 6 de la mañana :D. Al final la última noche compensó con creces el poco tiempo que habia pasado en el partyplace hasta el momento.

A las 7:00 cogimos el taxi hasta Portalegre, luego autobús a Lisboa, metro+bus para llegar hasta el aeropuerto, avión hasta Madrid, enlace por los pelos con el vuelo hacia Valencia, carrerita de un lado a otro de la terminal 4 de Barajas incluída (las maletas llegaron en el siguiente vuelo y esta mañana nos las han traido) y finalmente llegada a casa. Sin lugar a dudas ha sido el dia en el que más transbordos he hecho en toda mi vida.

En resumen, ha sido muy divertido, aunque ha sido una lastima que hubiera tan poca gente. No sé cuantos asistentes han tenido las últimas ediciones de la Inércia, pero me da la sensación de que les ha perjudicado hacer la party entre semana en una ciudad tan pequeña. Muchas gracias a ps y a evil por su labor como orgos, por invitarme a la party y por llevarnos de cena :)

Y dentro de 12 dias… BCN \o/

Comments (1)

Inercia Demoparty 2006

Estoy en Portalegre (Portugal) con PpluX pasando unos dias en la Inercia. Ayer pasamos todo el dia en las conferencias del Games2006, un congreso sobre videojuegos en el que está enmarcada este año la party. Muchas gracias a la organización de la party por invitarme :D

Ahora mismo estamos en el partyplace, y me dispongo a empezar una 4k. Supongo que haré un refrito de algo, voy a dedicar un par de horitas a experimentar a ver si encuentro algo chulo con lo que llenar la intro.

Si tengo tiempo y ganas seguiré contando cosas de la party en posts sucesivos.

Comments

This blog is protected by Dave\'s Spam Karma 2: 17770 Spams eaten and counting...