Is it possible to access the internal data for each supported file format
in SDL_Mixer? For example, I would like to access the song name for .XM
files. Reading through music.c and libMikMod’s documentation tells me
that I might be able to access the file’s song title like so:
Mix_Music *music;
/* opening a music file etc . . . */
/* assuming “music” points to an MikMod file */
char *title = music->data.module->songname;
However, this doesn’t work. In fact the following compiler error
is produced:
songname.cpp: In function int main (int, char **)': songname.cpp:47: invalid use of undefined type
struct _Mix_Music’
/usr/include/SDL/SDL_mixer.h:95: forward declaration of `struct
_Mix_Music’
Attached is a small program that illustrates the problem.
It seems the author’s of SDL_mixer chose to hide the internal workings of
the ‘Mix_Music’ type. Why do this? It seems to me that by hiding a music
format’s internal structure you may loose some the of the benefits of that
music format. For example, I might want to know the current bitrate of
the Ogg Vorbis file I’m currently playing.
Have I overlooked the method to gain this information through SDL_Mixer
or does a method simply not exist? If a method does not exist, why did
the authors decide not to include it.
Thanks,
Nathan Cournia
<@Cournia_Nathan_A>
//Compile: g++ songname.cpp -o songname -g sdl-config --libs --cflags
// -lSDL_mixer
//CTRL-C quits
#include
#include
#include <unistd.h>
#include “SDL.h”
#include “SDL_mixer.h”
using namespace std;
#define AUDIO_CHANNELS 2
#define AUDIO_RATE 44100
#define AUDIO_BUFFERS 4096
#define AUDIO_FORMAT AUDIO_S16
///////////////////////////////////////////////////////////////////////////////
int
main (int argc, char *argv[])
{
//arg check
if (argc != 2) {
cerr << argv[0] << " <song_file>" << endl;
exit (1);
}
//start SDL
if (SDL_Init (SDL_INIT_AUDIO) < 0) {
cerr << SDL_GetError() << endl;
exit (1);
}
atexit (SDL_Quit);
//start sound system
if (Mix_OpenAudio(AUDIO_RATE, AUDIO_FORMAT,
AUDIO_CHANNELS, AUDIO_BUFFERS) < 0) {
cerr << SDL_GetError() << endl;
exit (1);
}
atexit (Mix_CloseAudio);
//load music
Mix_Music *music = Mix_LoadMUS (argv[1]);
if (!music) exit (1);
Mix_PlayMusic (music, 0);
//XXX compiler doesn't like the following line
cerr << "Title: " << music->data.module->songname << endl;
while (Mix_PlayingMusic()) { sleep (1); }
//clean up
Mix_FreeMusic (music);
return 0;
} //end of main()