Archived

This topic is now archived and is closed to further replies.

Crash

SDL, SDL_Mixer and SMPEG For mp3 Playback

Recommended Posts

Has anyone here used SDL, SDL_Mixer and SMPEG for mp3 playback? It was recommended to me by someone on this board but unfortunatley Im having some problems with it as it is my first time using SDL. So does anyone know of any tutorials on SDL_Mixer and/or SMPEG that are aavailable apart from the one on the SDL website? Or if anyone has used it could you post some code for me to look over? Hoping someone can help, Crash, "We Must Move Forwards NOT Backwards, Sideways NOT Forwards And Always Twirling Twirling Towards Success." - 2000 "If You Keep Looking Forward Your Gonna End Up Looking Backwards At Yourself Running Sideways!" - 2001

Share this post


Link to post
Share on other sites
Oh another question, I assume you can use OpenGL for graphics and SDL for the sound and keyboard input, am I right?

Still Hoping,
Crash,

"We Must Move Forwards NOT Backwards, Sideways NOT Forwards And Always Twirling Twirling Towards Success." - 2000

"If You Keep Looking Forward Your Gonna End Up Looking Backwards At Yourself Running Sideways!" - 2001

Share this post


Link to post
Share on other sites
quote:
Original post by Crash
Has anyone here used SDL, SDL_Mixer and SMPEG for mp3 playback?

SDL Games Page
SDL Applications page
quote:
So does anyone know of any tutorials on SDL_Mixer and/or SMPEG that are aavailable apart from the one on the SDL website?

Some of the projects on the pages referred to above are Open Source.
quote:
...I assume you can use OpenGL for graphics and SDL for the sound and keyboard input, am I right?

Yes.

[ GDNet Start Here | GDNet FAQ | MS RTFM | STL | Google ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
If you want an actual answer read Oluseyi''s post . However: I found OpenAL much easier than bothering with SDL''s sound output and SDL_Mixer. I am using VorbisFile to easily stream from a compressed audio file (the OGG format is as good as, and debatably better, than the MP3 format ). So, if you get bored (or stuck), give it a try or something.

[Resist Windows XP''s Invasive Production Activation Technology!]

Share this post


Link to post
Share on other sites
I guess that means OpenAL doesn''t support mp3''s then Null And Void?

If not I cant use it really because I want to use mp3''s so that it is easier for the users to add their own music.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
  

#include "SDL.h"
#include "SDL_mixer.h"

SDL_InitSubSystem(SDL_INIT_AUDIO);
Mix_Music *music = Mix_LoadMUS("music.mp3");

/* -1 will loop forever */
MIX_PlayMusic(music, -1);

/* only one music can play at a given time (unlike sounds), so Mix_HaltMusic() takes no parameter.
*/
while (0 == MIX_PlayingMusic())
SDL_Wait(10); /* don''t hang the CPU in a busy loop */


Mix_HaltMusic();

Miix_FreeMusic(m_pMusic);
SDL_Quit();



You can do much more (adjust volume, pause, etc), but that''s the barebone to play a mp3. Of course if you want 3D sound, go for OpenAL.
For the rest, I strongly suggest than check out the source of SDL. It''s very easy to understand and is heavily commented.

Remeber to link it against the SDL_mixer library.

Hope this helps a bit.

Share this post


Link to post
Share on other sites
Thanks anonymous for that, I do though have one further problem. When I d/l SDL_Mixer it said I needed SMPEG to playback mp3''s with SDL_Mixer. Is this right? If so where do i need to use it? because your code and other code I have seen doesn''t seem to refer to it at all.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
SDL_Mixer acts as a sort of a front end to two other libraries (SMPEG and Ogg). It will use SMPEG to decode MP3 and the Ogg Vorbis library for Ogg. However, you don''t need to include any header other than SDL_mixer. You only have to install these libraries and to make sure than SDL_mixer was compiled with MP3 support.

If you compile SDL_mixer yourself (and have SMPEG installed), it will compile MP3 support by default. If you use precompiled binaries, it is probably built-in already ..

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You''re welcome .

I just spotted an error in my (mockery of a) code. SDL_Wait() doesn''t exist, it should be SDL_Delay(). Sorry if it caused any problem.

Share this post


Link to post
Share on other sites
No I spotted that, and its all working now. Thanks again for the help.

Crash,



"We Must Move Forwards NOT Backwards, Sideways NOT Forwards And Always Twirling Twirling Towards Success." - 2000

"If You Keep Looking Forward Your Gonna End Up Looking Backwards At Yourself Running Sideways!" - 2001

Share this post


Link to post
Share on other sites
Ok Ive got another problem now, Ive lost the sound. All the code compiles and links but theres no sound .

Here''s what Ive got so far:

//----------------------------------------------------------------------------
// PlayMusic()
// Plays Background Music
//----------------------------------------------------------------------------
void PlayMusic()
{
G.audio_rate = 22050;
G.audio_format = AUDIO_S16; /* 16-bit stereo */
G.audio_channels = 2;
G.audio_buffers = 4096;

SDL_InitSubSystem(SDL_INIT_AUDIO);
G.music = Mix_LoadMUS("Data/Music/Music001.mp3");
Mix_OpenAudio(G.audio_rate, G.audio_format, G.audio_channels, G.audio_buffers);
Mix_VolumeMusic(120);

// -1 will loop forever
Mix_PlayMusic(G.music, -1);
};

//----------------------------------------------------------------------------
// StopMusic()
// Stops Background Music
//----------------------------------------------------------------------------
void StopMusic()
{
Mix_HaltMusic();
Mix_FreeMusic(G.music);
SDL_Quit();
};

StopMusic() is called when the window is terminated, and PlayMusic() is called as below in my main game loop.

if(!Mix_PlayingMusic)
PlayMusic();

Im very confused, I can''t see where the music''s gone.

Oh so you know all my globals are found in a structure called G, thats why all the globals have G. in front of them. I know its nothing to do with that though because the structure is used in other parts of the program and it works there.

Hoping someone can help (...again),
Crash,



"We Must Move Forwards NOT Backwards, Sideways NOT Forwards And Always Twirling Twirling Towards Success." - 2000

"If You Keep Looking Forward Your Gonna End Up Looking Backwards At Yourself Running Sideways!" - 2001

Share this post


Link to post
Share on other sites
Oh a few other things, I am now using OpenGL and SDL in case that makes any difference.

And more importantly will SDL work if I set-up the window as a standard OpenGL window. And then just use SDL for SDL_mixer (mp3 playback) and keyboard/mouse events? I was just wondering because I''ve just seen the infomation on the SDL website about using the 2 APIs together and I just looked through NeHe''s SDL Basecode, and they are coded very different. Using SDL to set up the window rather then OpenGL.

Hope that makes sense, if not Ill try again in the mornin. When Im not so tired.

Hoping for a saviour,
Crash,



"We Must Move Forwards NOT Backwards, Sideways NOT Forwards And Always Twirling Twirling Towards Success." - 2000

"If You Keep Looking Forward Your Gonna End Up Looking Backwards At Yourself Running Sideways!" - 2001

Share this post


Link to post
Share on other sites
Of course OpenAL can''t play MP3''s. OpenAL (like all sound API''s) plays PCM formatted data. You must decode that data on your own. So, you can use SMPEG with OpenAL if you''d like, but I think using (and supporting) a truly free format like Ogg Vorbis is a nice gesture (given that it takes no more work that MP3 ).

OpenGL doesn''t know about things like windows. NeHe''s tutorials use the Win32 API to setup the window, not OpenGL. See page for an example of setting up a window with SDL for use with OpenGL. Also, most of NeHe''s tutorials have been ported to use SDL, if you''d like to look at the code behind those.

[Resist Windows XP''s Invasive Production Activation Technology!]

Share this post


Link to post
Share on other sites
I accept what your saying about Ogg Vorbis but the majority of my users will be my friends and ( Hmmm how do I say this without accusing anyone of anything, lets just say...) they all have alot of music they''d like to listen too whilst playing this game in mp3 format. Likewise there all far too dim to work out how to use Ogg Vorbis.

I like the idea of OpenAL, but as I have come this far with SDL and because Im now using it for numerous other things in this project I think I will complete it using SDL. Using OpenAL, would mean having to link in OpenGL, OpenAL and DirectInput amongst other things. And as this is my first *big* project I want to minimise the amount of libaries and APIs I include. Thanks for the suggestion though, because I may use OpenAL another time.

Still hoping someone can solve the original problem,
And still very grateful for all this help,
Crash,



"We Must Move Forwards NOT Backwards, Sideways NOT Forwards And Always Twirling Twirling Towards Success." - 2000

"If You Keep Looking Forward Your Gonna End Up Looking Backwards At Yourself Running Sideways!" - 2001

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You must call Mix_OpenAudio() before Mix_LoadMUS(), as it sets the audio format. If the format is incorrect (in this case it is), the file won''t be loaded.

Also, make sure than the format you''re using (22050, AUDIO_S16, 2) is actually correct for your file (load it in some editor/player, or just type ''file your_song.mp3'' on *nix if the magic number is set).

Hope this helps .

Share this post


Link to post
Share on other sites
Ok, is it possible to not use Mix_OpenAudio()? as I noticed it wasn''t in your example. If not and I am planning on using mutiple mp3s at different times in the game, will it be possible to change Mix_OpenAudio() each time I load a new mp3?

If this has to be done is there any other way to set Mix_OpenAudio? because I want my users to be able to set their own music, without having to hard-code these settings.

Slightly confused,
Crash,

"We Must Move Forwards NOT Backwards, Sideways NOT Forwards And Always Twirling Twirling Towards Success." - 2000

"If You Keep Looking Forward Your Gonna End Up Looking Backwards At Yourself Running Sideways!" - 2001

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Sorry, my example was actually just bad and written in a hurry. You must call Mix_OpenAudio() if you want to use SDL_mixer. If you don''t want to, you''ll have to work with the plain sound interface of SDL and SMPEG (or write your own loader etc if you don''t want to use SMPEG). I''d rather use OpenAL in that case.

SDL won''t allow you to change the format on the fly (that is, after it has been opened) IIRC, but I''m not sure about it. Maybe is there some hidden Mix_Reopen() or Mix_ChangeFormat() or something like that, but I don''t remember seeing anything remotely related to this in the source.

You could, of course, release the audio (Mix_CloseAudio()) and reopen it with another format, but you won''t be able to play anything until you reopen it. It will probably invalidate all the currently loaded sounds, but I''m not 100% sure, as they''re probably stored in the sound card''s internal format. Also, this will require that you first read the file header to gather the informations required.

AFAIK, that''s what mp3 players do, but it is not very convenient for games.

Remember to double check what I said: I haven''t used SDL_mixer in quite a while now, and the API, internals etc are probably slightly different now.

Share this post


Link to post
Share on other sites
Ok, I''ll have to think about that one. About finding out the details for the files, how would I do that? What programs would tell me that stuff because Ive tried with Sonique and Windows Media Player and all I can find is the audio rate. How could I get the other infomation I need for Mix_OpenAudio()?

Thanks again for all this help anonymous...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
On *nix, you could just type ''file music.mp3'' and get the required informations (as long as the magic number is set correctly). Sadly, I don''t know about any equivalent on Windows/Non-*nix Oses (feel free to prove me wrong, that would be helpful).

You could open the files in some hexadecimal editor, but that''s really too much work, IMO, and it doesn''t really solve your problem (to change format at runtime).

You''ll have to use the classic way and open the file with fopen/ifstream/etc, read the header and get the required values. Wotsit (http://www.wotsit.org) has a number of links to mp3 loaders code, specifications, etc.

Also, you''ll probably want to join the SDL mailing list (http://www.libsdl.org to register). It''s very active and helpful, and Sam is open to suggestions and quick to help. These guys certainly know the inners of SDL much better than I do and can answer just about anything related to SDL.

Finally, the source code of SMPEG is free (as in free speech), so you could just look into it and see how to read the MPEG header .

Sorry if I can''t provide much help here, but I don''t know much about the mp3 format (I use ogg vorbis), and I rely on libraries whenever possible.

Share this post


Link to post
Share on other sites
Crash, in regards to your previous question about using MP3s in DirectX, you can do so very easily using DirectShow. However don't think it comes with DirectX 7, but it does come with DirectX 8.

Here's some sample code to show how easy it is to play an MP3 file using DirectShow:

    
#include <dshow.h>

void main(void)
{
IGraphBuilder *pGraph;
IMediaControl *pMediaControl;
IMediaEvent *pEvent;
CoInitialize(NULL);

// Create the filter graph manager and query for interfaces.

CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (void **)&pGraph);
pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

// Build the graph. IMPORTANT: Change string to a file on your system.

pGraph->RenderFile(L"C:\\Example.mp3", NULL);

// Run the graph.

pMediaControl->Run();

// Wait for completion.

long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);

// Clean up.

pMediaControl->Release();
pEvent->Release();
pGraph->Release();
CoUninitialize();
}


DirectShow looks very duanting at first due to the sheer number of interfaces but you really need to concern yourself with IGraphBuilder, IMediaControl, IMediaEvent and IBasicAudio iterfaces.

You can also use it to play other audio file types like AU, AIFF, SND, etc.

- Kaijin

Edited by - Kaijin on January 2, 2002 2:08:31 PM

Share this post


Link to post
Share on other sites
Thanks alot anonymous, Im going to look through those resources tommorow morn and hopefully finally getting this to work.

Thanks also to Kaijin, I had just discovered I could use DirectShow but that codes a big help as Im seriously considering reverting to my original idea to use DirectX as then I wont have to worry about distributing my code (which is already in quite a state.)

Anyway till tommorow, when I will hopefully solve this problem and possibly complete this darn game.

Thanks guys,
Crash,



"We Must Move Forwards NOT Backwards, Sideways NOT Forwards And Always Twirling Twirling Towards Success." - 2000

"If You Keep Looking Forward Your Gonna End Up Looking Backwards At Yourself Running Sideways!" - 2001

Share this post


Link to post
Share on other sites