Skip to content
eXpl0it3r edited this page Oct 18, 2012 · 1 revision

Mp3 Player

By MickaGL

Works exclusively with the latest revision of SFML 2.

Here is a class using the library mpg123 which allows playback of MP3 files.
Works on the same principle that sf:: Music

Attention, decoding MP3 files is subject to strict licensing and is paid as part of a non-personal use.
http://www.mp3licensing.com

Mp3.h [Top]

#ifndef MP3_H_INCLUDED
#define MP3_H_INCLUDED

#include <SFML/Audio.hpp>
#include "mpg123.h"

namespace sfe
{
class Mp3 : public sf::SoundStream
{
public :
    Mp3();
    ~Mp3();

    bool OpenFromFile(const std::string& filename);

protected :
    bool OnGetData(Chunk& data);
    void OnSeek(sf::Time timeOffset);

private :
    mpg123_handle*      myHandle;
    size_t              myBufferSize;
    unsigned char*      myBuffer;
    sf::Mutex           myMutex;
};

} // namespace sfe

#endif // MP3_H_INCLUDED

Mp3.cpp [Top]

#include "Mp3.h"
#include <iostream>

namespace sfe
{
Mp3::Mp3() :
myHandle    (NULL),
myBufferSize(0),
myBuffer    (NULL)
{

}

Mp3::~Mp3()
{
    Stop();

    if (myBuffer)
    {
        delete [] myBuffer;
        myBuffer = NULL;
    }

    mpg123_close(myHandle);
    mpg123_delete(myHandle);
    mpg123_exit();
}

bool Mp3::OpenFromFile(const std::string& filename)
{
    Stop();

    int  err = MPG123_OK;
    if ((err = mpg123_init()) != MPG123_OK)
    {
        std::cerr << mpg123_plain_strerror(err) << std::endl;
        return false;
    }

    myHandle = mpg123_new(NULL, &err);
    if (!myHandle)
    {
        std::cerr << "Unable to create mpg123 handle: " << mpg123_plain_strerror(err) << std::endl;
        return false;
    }

    if (mpg123_open(myHandle, filename.c_str()) != MPG123_OK)
    {
        std::cerr << mpg123_strerror(myHandle) << std::endl;
        return false;
    }

    long rate = 0;
    int  channels = 0, encoding = 0;
    if (mpg123_getformat(myHandle, &rate, &channels, &encoding) != MPG123_OK)
    {
        std::cerr << "Failed to get format information for 464480e9ee6eb73bc2b768d7e3d7865aa432fc34quot;" << filename << "464480e9ee6eb73bc2b768d7e3d7865aa432fc34quot;" << std::endl;
        return false;
    }

    myBufferSize = mpg123_outblock(myHandle);
    myBuffer = new unsigned char[myBufferSize];
    if (!myBuffer)
    {
        std::cerr << "Failed to reserve memory for decoding one frame for 464480e9ee6eb73bc2b768d7e3d7865aa432fc34quot;" << filename << "464480e9ee6eb73bc2b768d7e3d7865aa432fc34quot;" << std::endl;
        return false;
    }

    Initialize(channels, rate);

    return true;
}

bool Mp3::OnGetData(Chunk& data)
{
    sf::Lock lock(myMutex);

    if (myHandle)
    {
        size_t done;
        mpg123_read(myHandle, myBuffer, myBufferSize, &done);

        data.Samples   = (short*)myBuffer;
        data.SampleCount = done/sizeof(short);

        return (data.SampleCount > 0);
    }
    else
        return false;
}

void Mp3::OnSeek(sf::Time timeOffset)
{
    sf::Lock lock(myMutex);

    if (myHandle)
        mpg123_seek(myHandle, timeOffset.AsSeconds(), 0);
}

} // namespace sfe

main.cpp [Top]

#include <SFML/Graphics.hpp>
#include "Mp3.h"

int main()
{
    sf::RenderWindow application(sf::VideoMode::GetDesktopMode(), "", sf::Style::Fullscreen);

    sfe::Mp3 musique;
    if (!musique.OpenFromFile(("music.mp3"))
        exit(EXIT_FAILURE);
    musique.Play();

    while (application.IsOpen())
    {
        sf::Event evenement;
        while (application.PollEvent(evenement))
        {
            if ((evenement.Type == sf::Event::KeyPressed) && (evenement.Key.Code == sf::Keyboard::Escape))
                application.Close();

            if ((evenement.Type == sf::Event::KeyPressed) && (evenement.Key.Code == sf::Keyboard::P))
            {
                if (musique.GetStatus() != sf::SoundStream::Paused)
                    musique.Pause();
                else
                    musique.Play();
            }
        }

        if (musique.GetStatus() != sf::SoundStream::Playing && musique.GetStatus() != sf::SoundStream::Paused)
            application.Close();

        application.Clear();

        application.Display();
    }

    return EXIT_SUCCESS;
}
Clone this wiki locally