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.