En el anterior post de este tutorial se explicó como se puede hacer para reproducir módulos musicales pero no llegamos a ver un ejemplo adaptado en condiciones para usarlo con SDL en C. El ejemplo era funcional pero sin ventanita y sin control para poder cerrar.
En este caso he adaptado el ejemplo que ofrece libxmp para usarlo junto a SDL. Digamos que este ejemplo va mucho más en la línea del resto de artículos.
Aquí puede bajarse el zip con el código y el makefile listo para hacer make clean y make build: playmod2.tar.gz
El zip lleva varios módulos para use y disfrute. El código simplemente crea una ventana y espera a que la cierres para finalizar (pero mientras suena la música).
No he metido nada en la ventana para no añadir código que pueda inducir a error o resultar molesto.
Veamos el código:
#include <SDL.h>
#include <xmp.h>
#include <stdbool.h>
int sonando;
char * modulo = "res/aladin.mod";
static void rellenarAudio(void *udata, Uint8 *stream, int len)
{
if (xmp_play_buffer((xmp_context)udata, stream, len, 0) < 0){ sonando = 0; }
}
static int sdl_init(xmp_context ctx) {
if (SDL_Init(SDL_INIT_AUDIO) < 0) { printf("No se ha podido inicializar: %s\n", SDL_GetError()); return 1; }
SDL_AudioSpec a;
a.freq = 44100;
a.format = AUDIO_S16;
a.channels = 2;
a.samples = 2048;
a.callback = rellenarAudio;
a.userdata = ctx;
if (SDL_OpenAudio(&a, NULL) < 0) { printf("No se ha podido inicializar el dispositivo de audio: %s\n", SDL_GetError()); return 1; }
return 0;
}
int main(int argc, char **argv) {
SDL_Event evento;
bool quit = false;
SDL_Window * ventana;
SDL_Init(SDL_INIT_VIDEO);
ventana = SDL_CreateWindow("Modulo sonando de fondo",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,320,240,SDL_WINDOW_OPENGL);
if (ventana == NULL) { printf("No se pudo crear la ventana: %s\n", SDL_GetError()); return 1; }
xmp_context ctx;
ctx = xmp_create_context();
sdl_init(ctx);
xmp_load_module(ctx, modulo);
xmp_start_player(ctx, 44100, 0);
sonando = 1;
SDL_PauseAudio(0);
while (!quit) {
SDL_WaitEvent(&evento);
switch (evento.type) {
case SDL_QUIT:
xmp_end_player(ctx);
xmp_free_context(ctx);
SDL_CloseAudio();
quit = true;
break;
}
}
}
Podemos ver que se han declarado 2 funciones antes del main y que cargamos en modulo = «res/aladin.mod» (Lo mismo si lo escuchas te suena el tema).
Cuando el evento de cerrar se active se descargará el modulo y se cerrará la ventana. También es bueno comentar que se ha usado la función: SDL_AudioSpec
Y bueno. Supongo que con esto ya se tiene un ejemplo de como cargar un modulo de sonido y hacer que suene en nuestro programa.
En este ejemplo se carga al inicio y no se para hasta que cerramos la ventana. Pero nada nos impide como vimos en el ejemplo del teclado hacer que se inicie en otro momento o que se inicie usando una tecla y que se pare pulsando otra.
Digamos que como en los módulos podemos cargar un solo sample o un solo instrumento y hacer que suene como queramos podríamos crear una combinación de sonidos que suenen cuando pulsamos una tecla u otra y crearnos una caja de ritmos o simplemente para un programa de radio tener sonidos de aplausos, risas enlatadas, …
Saludos cordiales.

