Saltar al contenido
56K

56K

Slow IT Notes – Just 4 Fun

Menú
Menú

SDL en C bajo GNU/Linux – 009 – Cientos de tipos de módulos de sonido

Publicada el 24/10/202106/02/2023 por fanta

xmp es un player para línea de comandos que soporta un montón de módulos musicales y al mismo tiempo es una librería (está desarrollado sobre esa librería) que nos permite utilizarla para por ejemplo reproducir módulos en nuestros programas.

 

En este articulo simplemente vamos a integrar la librería xmp.h junto con SDL.h y ver como podemos trabajar con cientos de tipos diferentes de módulos e integrarlos en nuestros programas/demos/juegos/… con SDL2.

Información sobre xmp y libxmp (versión 4.4.1):

Website: xmp.sourceforge.net/
API documentación: xmp.sourceforge.net/libxmp.html
Ejemplos: xmp.sourceforge.net/examples/
Descargar libxmp: libxmp-4.4.1 aquí.

Instalar libxmp-dev en Debian/Ubuntu:

apt-get install libxmp-dev

 

Entre los módulos que soporta (más de 90) este player y su librería podemos destacar estos:

  • Protracker
  • OctaMED
  • MilkyTracker
  • Fast Tracker
  • Fast Tracker II
  • Impulse Tracker
  • DIGI Booster
  • Scream Tracker 2
  • Scream Tracker 3
  • Ice Tracker
  • Oktalyzer
  • Composer 669
  • Digitrakker
  • Farandole Composer
  • Funktracker
  • Imago Orpheus
  • Liquid Tracker
  • Multitracker
  • Poly Tracker
  • Real Tracker
  • TakeTracker
  • Ultra Tracker
  • X-Tracker
  • Game Music Creator (GMC)
  • Galaxy Music System
  • Digital Tracker
  • Flextrax
  • Graoumf Tracker
  • Octalyser
  • TCB Tracker
  • Archimedes Tracker
  • …

 

Al margen de que con SDL2 base se puede reproducir wav y que con otras librerías podemos reproducir ogg, mp3, … la idea es poder secuenciar módulos más que otra cosa. Eso nos permite tener acceso a los instrumentos e incluso mutear canales.

Yo prefiero usar xmp.h ahora mismo para poder incluir música molona que se genera en tiempo de ejecución. No obstante en futura entradas veremos que para un ogg o un mp3 no necesitamos añadir nada extra.

Lo primero es probar que la cosa funciona bien. Si hemos instalado la librería (tanto sdl base como libxmp-dev) vamos a ver uno de los ejemplos que ofrecen junto a la librería xmp.

 

Descargar el código de ejemplo con módulos de sonido y todos los directorios necesarios: playmod.tar.gz

 

El makefile que solemos usar ha sufrido en este caso una alteración (-lxmp) para poder compilar:

 

CC := gcc
CFLAGS := -Wall
LINKER_FLAGS = `sdl2-config --cflags --libs` -lxmp

test:
	make clean
	make build

build:
	$(CC) $(CFLAGS) -o bin/playmod playmod.c $(LINKER_FLAGS)

run:
	./bin/playmod

clean:
	-rm bin/playmod

 

 

Y aquí va el código de ejemplo que viene con libxmp (que guardamos en un archivo llamado playmod.c:

 

 

#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include <xmp.h>


static int playing;

static void fill_audio(void *udata, Uint8 *stream, int len)
{
	if (xmp_play_buffer((xmp_context)udata, stream, len, 0) < 0)
		playing = 0;
}

static int sdl_init(xmp_context ctx)
{
	SDL_AudioSpec a;

	if (SDL_Init(SDL_INIT_AUDIO) < 0) {
		fprintf(stderr, "sdl: can't initialize: %s\n", SDL_GetError());
		return -1;
	}

	a.freq = 44100;
	a.format = AUDIO_S16;
	a.channels = 2;
	a.samples = 2048;
	a.callback = fill_audio;
	a.userdata = ctx;

	if (SDL_OpenAudio(&a, NULL) < 0) {
		fprintf(stderr, "%s\n", SDL_GetError());
		return -1;
	}

	return 0;
}

static void sdl_deinit()
{
	SDL_CloseAudio();
}

int main(int argc, char **argv)
{
	xmp_context ctx;
	struct xmp_module_info mi;
	struct xmp_frame_info fi;
	int i;

	ctx = xmp_create_context();

	if (sdl_init(ctx) < 0) {
		fprintf(stderr, "%s: can't initialize sound\n", argv[0]);
		exit(1);
	}

	for (i = 1; i < argc; i++) {
		if (xmp_load_module(ctx, argv[i]) < 0) {
			fprintf(stderr, "%s: error loading %s\n", argv[0],
				argv[i]);
			continue;
		}

		if (xmp_start_player(ctx, 44100, 0) == 0) {

			/* Show module data */

			xmp_get_module_info(ctx, &mi);
			printf("%s (%s)\n", mi.mod->name, mi.mod->type);

			/* Play module */

			playing = 1;
			SDL_PauseAudio(0);

			while (playing) {
				SDL_Delay(10);
				xmp_get_frame_info(ctx, &fi);
				printf("%3d/%3d %3d/%3d\r", fi.pos,
					mi.mod->len, fi.row, fi.num_rows);
				fflush(stdout);
			}
			xmp_end_player(ctx);
		}

		xmp_release_module(ctx);
		printf("\n");
	}

	xmp_free_context(ctx);

	sdl_deinit();

	return 0;
}

 

En el directorio res dentro de bin he dejado algunos modulos de ejemplo ( 56k.es/wp-content/uploads/2021/01/mods.zip ). No necesitas descargarlos si has bajado el tar.gz con el código de ejemplo.

 

Lo compilamos con make en el directorio en el que tenemos el makefile. (make build)

De modo que para probar si chuta así:

cd bin
./playmod res/lickit.mod

 

Veremos algo como esto:

 

 

Lo cierto es que el ejemplo sirve para saber que la cosa chuta pero no es lo óptimo. Lo ideal es usarlo en nuestro programa para elegir desde este cuando sonará un modulo y que modulo será.

Con paciencia poco a poco.

 

Información sobre los módulos importante.

Hace un tiempo que programé un player para módulos formato protracker (para AmigaOS 4.1).

 

Me tocó buscar mucha documentación sobre como funcionan realmente estos módulos. Este texto rescatado de textfiles.com me sirvió de mucha ayuda: www.textfiles.com/programming/AMIGA/protrack.ami.

Aunque tiene extensión ami es un texto plano que puedes abrir con cualquier editor.

También puede ser de utilidad este texto con conclusiones sacadas a través de ingeniería inversa: www.textfiles.com/programming/FORMATS/modulesg.txt

Lo interesante es que cuando cargas un archivo y lo atacas podrás ir posicionándote para sacar la información que necesitas para reproducirlo. En ese archivo se define por ejemplo donde se almacena el titulo de un modulo. el nombre de los samples, …:

Offset  Bytes  Description
------  -----  -----------
   0     20    Songname. Remember to put trailing null bytes at the end...
  20     22    Samplename for sample 1. Pad with null bytes.

 

Es bueno conocer como son estos archivos y su estructura, no obstante como estamos tirando de libxmp no necesitaremos conocer tanto y vamos a poder realizar la mayoría de cosas sin siquiera saber mucho sobre los módulos. Nos dedicaremos a cargar música, pausar música, pararla, extraer información de los módulos y poco más.

Si andas en GNU+Linux aquí tienes un post que lo mismo te permite entender más a fondo el formato mod protracker: 56k.es/fanta/anatomia-binaria-de-un-mod-protracker-con-dd/

 

Salvo que queramos realizar un editor tracker en SDL lo normal es que usemos la librería para simplemente reproducir música.
Y que si queremos un tracker en SDL milkytracker es crema.

 

Saludos cordiales.


fanta

Escrito por Fanta

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

fanta de naranja
Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors
💾 QEMU
💾 SOLARIS
💾 ESXi
💾 FREEBSD
💾 DEBIAN
💾 AMIGA
💾 SYSADMIN
💾 JUNOS
💾 IMPRIMIR
💾 MSDOS
💾 WINDOWS
💾 FAIRPHONE
💾 GAMING
💾 STREAMING
💾 REDHAT
💾 GRÁFICOS
💾 CACHARROS
💾 SONIDO
💾 NETWORKING
💾 ROCKY
💾 SUSE
💾 TMP
©2025 56K | Construido utilizando WordPress y Responsive Blogily tema por Superb