Play Module With Mikmod.h


JyCet

Member
Joined
Feb 23, 2004
Messages
469
Age
118
Location
France
Website
Visit site
Hi all,
Now I test how work mikmod library without SDL_mixer (I really dislike this lib)
Here the test code
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <SDL/SDL.h>
#include <mikmod.h>

MODULE *module;

int main(int argc, char *argv[])
{
	SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO  | SDL_INIT_AUDIO);
	ecran = SDL_SetVideoMode(320, 240, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
	SDL_ShowCursor (0); //desactive souris
	SDL_JoystickOpen(0);
	
	MikMod_RegisterAllDrivers();
	MikMod_RegisterLoader(&load_mod);
	md_mode |= DMODE_SOFT_MUSIC;
	MikMod_Init("");
	module = Player_Load("sommar.mod", 32, 0 );
	if (module) {
		Player_Start(module);
		while (Player_Active()){
		MikMod_Update();
		}		
	Player_Stop();
	Player_Free(module);
	}else printf("impossible de lire le module\n");

	MikMod_Exit();	

	SDL_JoystickClose(0);
	chdir("/usr/gp2x");
	execl("gp2xmenu","gp2xmenu",NULL);
	SDL_Quit();
	return 0;
}

The compilation is OK, but the gpe give a big music.raw file on the SD.

First idea, the mikmod driver is not correct to ear the sound but which one is correct for GP2X hardware?
Code:
MIKMODAPI extern struct MDRIVER drv_nos;	/* no sound */
MIKMODAPI extern struct MDRIVER drv_pipe;   /* piped output */
MIKMODAPI extern struct MDRIVER drv_raw;	/* raw file disk writer [music.raw] */
MIKMODAPI extern struct MDRIVER drv_stdout; /* output to stdout */
MIKMODAPI extern struct MDRIVER drv_wav;	/* RIFF WAVE file disk writer [music.wav] */
MIKMODAPI extern struct MDRIVER drv_aiff;   /* AIFF file disk writer [music.aiff] */

MIKMODAPI extern struct MDRIVER drv_ultra;  /* Linux Ultrasound driver */
MIKMODAPI extern struct MDRIVER drv_sam9407;	/* Linux sam9407 driver */

MIKMODAPI extern struct MDRIVER drv_AF;	 /* Dec Alpha AudioFile */
MIKMODAPI extern struct MDRIVER drv_aix;	/* AIX audio device */
MIKMODAPI extern struct MDRIVER drv_alsa;   /* Advanced Linux Sound Architecture (ALSA) */
MIKMODAPI extern struct MDRIVER drv_esd;	/* Enlightened sound daemon (EsounD) */
MIKMODAPI extern struct MDRIVER drv_hp;	 /* HP-UX audio device */
MIKMODAPI extern struct MDRIVER drv_oss;	/* OpenSound System (Linux,FreeBSD...) */
MIKMODAPI extern struct MDRIVER drv_sgi;	/* SGI audio library */
MIKMODAPI extern struct MDRIVER drv_sun;	/* Sun/NetBSD/OpenBSD audio device */

MIKMODAPI extern struct MDRIVER drv_dart;   /* OS/2 Direct Audio RealTime */
MIKMODAPI extern struct MDRIVER drv_os2;	/* OS/2 MMPM/2 */

MIKMODAPI extern struct MDRIVER drv_ds;	 /* Win32 DirectSound driver */
MIKMODAPI extern struct MDRIVER drv_win;	/* Win32 multimedia API driver */

MIKMODAPI extern struct MDRIVER drv_mac;	/* Macintosh Sound Manager driver */
MIKMODAPI extern struct MDRIVER drv_osx;	/* MacOS X CoreAudio Driver */

Second idea mikmod lib need a little SDL sound initialisation ?
:(
 
Hello Jycet

Try to see which driver are in working in your libs with the following commands :

fprintf(logFile, "Driver\n------\n%s\n\n", MikMod_InfoDriver());
fprintf(logFile, "Loader\n------\n%s\n\n", MikMod_InfoLoader());

You should have something similar to this :

Driver
------
1 DirectSound Driver (DX6+) v0.4
2 Raw disk writer (music.raw) v1.1
3 Wav disk writer (music.wav) v1.2
4 Standard output driver v1.1
5 Nosound Driver v3.0

Just the first one for Linux on the GP2X should be the OSS (Open Sound System), I know I had to remake my own version of mikmod libs since the one I had give the same trouble (I spend a long time trying to fix it). If yours have the same trouble let me know I could send your my compiled version.
 
Thanks for your help !

Here my log:
Code:
Driver
------
 1 Raw disk writer (music.raw) v1.1
 2 Wav disk writer (music.wav) v1.2
 3 Piped Output driver v0.2
 4 Standard output driver v1.1
 5 Nosound Driver v3.0

Loader
------
669 (Composer 669, Unis 669)
AMF (DSMI Advanced Module Format)
DSM (DSIK internal format)
FAR (Farandole Composer)
GDM (General DigiMusic)
IT (Impulse Tracker)
IMF (Imago Orpheus)
MOD (31 instruments)
MED (OctaMED)
MTM (MultiTracker Module editor)
OKT (Amiga Oktalyzer)
S3M (Scream Tracker 3)
STM (Scream Tracker)
STX (Scream Tracker Music Interface Kit)
ULT (UltraTracker)
APUN (APlayer) and UNI (MikMod)
XM (FastTracker 2)
MOD (15 instrument)

Unfortunatly no OSS driver, so when I use it ... the progr crash :(
Currently I use the default MIKMOD lib of devkitgp2x under winxp.

I would like to test with your compiled lib of MIKMOD if it's possible.
Thank you :)
 
Hello JyCet

Ok I see it is exactly the problem I got when first using the mikmod libs ;-), ill have to send the one I compiled, tough I compiled them to get working on the standard SDK so it might have some issue with linking.

Ill have to send you this later as now I am going to watch some movie with my wife ;-) (sorry).

Also you can pm me to remind me (you can use french, as I am a Quebecois and saw your a Francais ;-)).

A+
Fred
 
Sorry to hijack this thread, but I'm also having some problems with Mikmod. I can't get it to produce any sound output, although theoretically it is playing (it even produces that ~9mb music.raw file).

Here's my code:

Code:
#include "mikmod.h"

...

SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER); // it doesn't work if I don't initialize AIUDIO, either

...

MikMod_RegisterAllDrivers();
MikMod_RegisterAllLoaders();
md_mode |= DMODE_SOFT_MUSIC;
if(MikMod_Init("")) // draw something on screen, taken out of example

MODULE* module = NULL;
module = Player_Load("battle.mod", 64, 0);
if(module) {
  if(MikMod_EnableOutput())  // draw something on screen, taken out of example
  Player_SetVolume(124);
  Player_Start(module);
  Player_SetVolume(124);
  while(Player_Active()) {
	MikMod_Update();
  }
  Player_Stop();
  Player_Free(module);
  MikMod_Exit();
} else   // draw something on screen, taken out of example

MikMod is my last chance of getting mod playback with reliable volume settings going. It's very weird though, as after the song is done, the rest of the program executes. So I asusme that it's actually doing playback, just without output...

Thanks for any help!

- Alex
 
No problem Alex., I hope we will find a solution and share it for everybody, because the use of sdl_mixer only to play some sample and some module it's pity !

;)
 
I have a quick-patch suggestion, why not write a 0 or 2 byte file over music.raw to bypass its large size? Would that work?

Also, do you have any ideas why it doesn't output any sound for me? I use the mikmod.h included in DevKitGP2X, downloaded sometime in June 2006.

- Alex
 
My idea is because like me you dont have the correct output driver detected by MikMod_RegisterAllDrivers();. The correct driver is probably missing.
You have music.raw file because mikmod use drv_raw driver for gp2x :(

One of solution is perhaps write a wav file in .../dsp but i dont know if it's really possible, second solution is write a correct driver for gp2x linux, for me it's the most logical solution for high compatibility and I think it's intruder solution too.

I'm waiting his lib to test ;)
 
If it works drop me a line, I'd love to use it myself :)

Also, SuperTux uses mikmod directly, successfully! Perhaps the author used a different version of the lib?

- Alex
 
Howd you all go with this guys?

Im trying to use it to play a mod, but Im getting zero volume.

Also, how often would I need to call Mikmod_update?

When I run my test program everything appears to happen ok (loading of the module etc) except I simply get zero sound coming out - and I dont get music.raw file, and I do have the OSS driver.

Anyone got this working reliably?

EDIT : Man, I gotta learn to give it a chance first - I was accidentally calling Mikmod_init twice, which was killing it,

Mod-o-rama.

BTW, the answer to my second question was: once a frame appears to be fine.
 
So you got it working? I still get zero volume :( Do you think you could kindly post the code relevant to it, I'd really like to get it working myself :)

Thanks!

- Alex
 
So you got it working? I still get zero volume :( Do you think you could kindly post the code relevant to it, I'd really like to get it working myself :)

Thanks!

- Alex

Yup, here's some code - I took someone else's example 'bounce an image around the screen' SDL example and altered it for hw accel and mod playing.

Im a C and SDL noob, so if Ive made any massive blunders let me know! (for example, shouldnt SDL_Event event; be declared outside of the while loop? and Im sure I should be locking the surface to clear it.....). Let me know if it does/doesnt work for you.

EDIT: oh, and btw the code that attempts to read the buttons is something I hacked in which doesnt work - Im not entirely sure how the volume works for mikmod (I seem to get 100% volume all the time) and the read of keys acts strangely........

DOUBLE EDIT: I should also point out that Im using revision 182 from open2x svn, except for SDL (Im using Paeryn's most recent binary, as their makefiles in svn have big problems).

Code:
#include <SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "mikmod.h"
static int pos_x = 0; static char x_dir = 0;
static int pos_y = 0; static char y_dir = 0;



void clearScreen(SDL_Surface * screen) {
	int i, j;
	for (i = 0; i < screen->h; i++) {
		for (j = 0; j < screen->w; j++) {
		  *(((unsigned long*)screen->pixels) + i * (screen->pitch / 4) + j) = 0x000000;
		}
	}
}

void drawSprite(SDL_Surface* imageSurface, SDL_Surface* screenSurface, int srcX, int srcY, int dstX, int dstY, int width, int height) {
	SDL_Rect srcRect; 
	srcRect.x = srcX;
	srcRect.y = srcY;
	srcRect.w = width;
	srcRect.h = height;

	SDL_Rect dstRect;
	dstRect.x = dstX;
	dstRect.y = dstY;
	dstRect.w = width;
	dstRect.h = height;

	SDL_BlitSurface(imageSurface, &srcRect, screenSurface, &dstRect);
}

int main(int argc, char *argv[]) {
	atexit( SDL_Quit );
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_AUDIO) < 0)
		return 1;
 
	SDL_Surface *screen;
	int done = 0;

	screen = SDL_SetVideoMode(320, 240, 16, SDL_HWSURFACE | SDL_DOUBLEBUF); // Hardware surfaces, double buffered
	if (!screen) {
		fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
		return 1;
	}
	SDL_ShowCursor (0);
	SDL_JoystickOpen(0);
	SDL_ShowCursor(SDL_DISABLE);
	SDL_Surface* bitmap_tmp = SDL_LoadBMP("image.bmp");
	SDL_Surface* bitmap = SDL_DisplayFormat(bitmap_tmp); // Convert to hardware surface
	bitmap_tmp = NULL;

	MODULE *module;
	int volume = 64;
	MikMod_RegisterAllDrivers();
	MikMod_RegisterAllLoaders();
	md_mode |= DMODE_SOFT_MUSIC;
	if (MikMod_Init("")) {
		fprintf(stderr, "Could not initialize sound, reason: %s\n",
				MikMod_strerror(MikMod_errno));
		return -1;
	}
	module = Player_Load("awake.mod", 64, 0);
	
	if (module){
		printf ("Loaded module successfully?\n");
		printf("Driver\n------\n%s\n\n", MikMod_InfoDriver());
		printf("Loader\n------\n%s\n\n", MikMod_InfoLoader());
		Player_SetVolume(volume);
		Player_Start(module);   
	}
	
	while (!done) {
		SDL_Event event;

		SDL_PollEvent(&event);

		switch (event.type) {
			case SDL_JOYBUTTONUP:
				switch(event.jbutton.button)
				{
					case 15: /* X pressed */
						done = 1;
						break;
					case 16: /* L pressed */
						volume += 16;
						printf("Volume = %d",volume);
						break;
					case 17: /* L pressed */
						volume -= 16;
						printf("Volume = %d",volume);
						break;
				}			
				break;
			case SDL_QUIT:
				done = 1;
				break;
		}
		// bounce the logo around a bit
		if (x_dir == 0) {
			++pos_x;
			if ( (pos_x + bitmap->w) >= screen->w )
				x_dir = 1;
		}
		else {
			--pos_x;
			if ( pos_x <= 0 )
				x_dir = 0;
		}
		if (y_dir == 0) {
			++pos_y;
			if ( (pos_y + bitmap->h) >= screen->h )
				y_dir = 1;
		}
		else {
			--pos_y;
			if ( pos_y <= 0 )
				y_dir = 0;
		}

		clearScreen( screen );
		drawSprite(bitmap, screen, 0, 0, pos_x, pos_y, bitmap->w, bitmap->h);
		SDL_Flip(screen);
		if (Player_Active()){
			MikMod_Update();
		}		
	} 
	Player_Stop();
	Player_Free(module);
	MikMod_Exit();
	chdir("/usr/gp2x");
	execl("gp2xmenu","gp2xmenu",NULL);
	return 0;
}
 
Last edited by a moderator:
Thanks for that Simon, I tried it but I couldn't get it to output any sound. The game experienced serious lag though, so I assume it was working besides the sound output :D

I'll just stick to OGG from now on, getting mod playback on this thing is a bloody headache.

- Alex
 
OGG would have to be heavier than MOD??!?!

What firmware are you running?

If I send you the binary for this can you check if it works? Im wondering if your devkit is broken somehow......
 
Of course please do send it!

artraid
at
gmail
dot
com

- Alex
 
I tried it, and it doesn't output any sound.

This is rather baffling, I'm running firmware 2.1.1

- Alex
 
From memory so am I.

Have you made any changes to your firmware? Perhaps you should consider reflashing it?

Very very weird. I cant understand it, because /dev/dsp is /dev/dsp. If you can get sound, you can get sound. What would be the difference between playing a mod and playing an ogg?
 
No, for playing an OGG I use SDL_mixer. However, SDL_mixer has trouble handling large .mod files, which is why I turned to mikmod.

I tried this with both firmwares 2.1.0 and 2.1.1, and it doesn't work with either. Perhaps I should re-flash to 2.0.0, and upgrade again.

- Alex
 
so, I compiled a binary that works on my gp2x, but doesnt work on yours?

Perhaps some others would test it for us?
 
I'd like to test. I'm having troubles getting mikmod to work.

edit: more info

I'm not seeing the OSS driver. I'm on firmware 2.1.1.

1 Raw disk writer (music.raw) v1.1
2 Wav disk writer (music.wav) v1.2
3 Piped Output driver v0.2
4 Standard output driver v1.1
5 Nosound Driver v3.0

I end up with a big music.raw file and I see my framerate take a big hit when I'm running.

I'm using the libmikmod from DJWillis toolchain.

When linking, I see:

C:/devkitGP2X/lib\libmikmod.a(mdriver.o): In function `MD_DropPrivileges':
../playercode/mdriver.c:919: warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

This seems important.
 
Back
Top