lunes, 10 de mayo de 2010

Clase para reproducir sonido con MCI

Esta tarde he estado haciendo un clase para poder reproducir música en formatos como mp3, wav, y dependiendo del sistema operativo o codecs instalados aac, ogg, pero no estoy seguro.

Para ello uso MCI, que realmente vale para muchísimas otras cosas, como reproducir o capturar vídeo de un archivo o de hardware como una webcam, reproducir midi y formatos anteriores,...

#include <windows.h>
#include <iostream>
#include <string>

enum mode {unknown, open, playing, paused, stopped };

class MCI
{
    // davidxl.blogspot.com
    private:
        std::string filename;
        unsigned int lenght;
        int volume;
        int balance;

    public:
        MCI() : lenght(0),volume(1000),balance(0)
        {

        };

        MCI(std::string filename): volume(1000),balance(0)
        {
            Open(filename);
        };

        ~MCI()
        {
            Close();
        }

        void Open(std::string filename)
        {
            Close();
            this->filename = filename;
            std::string msg = "open \"" + filename + "\" type mpegvideo alias " + filename;
            mciSendString(msg.c_str(), NULL, 0, 0);
            lenght = Lenght(true);
        }

        void Play(int pos = 0)
        {
            char *buff = new char[10];
            std::string msg = "play " + filename + " from " + itoa(pos,buff,10);
            mciSendString(msg.c_str(), NULL, 0, 0);
            delete [] buff;
        }

        void Seek(int pos)
        {
            char *buff = new char[10];
            std::string msg = "seek " + filename + " to " + itoa(pos,buff,10);
            mciSendString(msg.c_str(), NULL, 0, 0);
            delete [] buff;
        }

        void Pause()
        {
            std::string msg = "pause " + filename;
            mciSendString(msg.c_str(), NULL, 0, 0);
        }

        void Resume()
        {
            std::string msg = "resume " + filename;
            mciSendString(msg.c_str(), NULL, 0, 0);
        }

        void Stop()
        {
            std::string msg = "stop " + filename;
            mciSendString(msg.c_str(), NULL, 0, 0);
        }

        void Close()
        {
            std::string msg = "close " + filename;
            mciSendString(msg.c_str(), NULL, 0, 0);
        }

        int Volume()
        {
            return volume;
        }

        void Volume(int vol)
        {
            vol = (vol < 0 ? 0 : (vol > 1000 ? 1000 : vol));
            char *buff = new char[5];
            std::string msg = "setaudio " + filename + " volume to " + itoa(vol,buff,10);
            mciSendString(msg.c_str(), NULL, 0, 0);
            delete [] buff;
        }

        int Balance()
        {
            return balance;
        }

        void Balance(int bal)
        {
            bal = (bal < -1000 ? -1000 : (bal > 1000 ? 1000 : bal));
            char *buff = new char[5];
            std::string msg = "setaudio " + filename + "left volume to " + itoa((bal<0?1000:1000-bal),buff,10);
            mciSendString(msg.c_str(), NULL, 0, 0);
            msg = "setaudio " + filename + "right volume to " + itoa((bal>0?1000:1000+bal),buff,10);
            mciSendString(msg.c_str(), NULL, 0, 0);
            delete [] buff;
        }

        int Lenght(bool refresh = false)
        {
            if (refresh)
            {
                char *buff = new char[128];
                std::string msg = "status " + filename + " length";
                mciSendString(msg.c_str(), buff, 128, 0);
                int t = atoi(buff);
                delete [] buff;
                return t;
            }
            else
            {
                return lenght;
            }
        }

        int Position()
        {
            char *buff = new char[16];
            std::string msg = "status " + filename + " position";
            mciSendString(msg.c_str(), buff, 16, 0);
            int t = atoi(buff);
            delete [] buff;
            return t;
        }

        int Position(int ms)
        {
            if (status() == playing || status() == paused)
                Seek(ms);
            else
                Play(ms);
        }

        mode status()
        {
            char *buff = new char[8];
            std::string msg = "status " + filename + " mode";
            mciSendString(msg.c_str(), buff, 8, 0);
            mode ret;
            if (strncmp(buff,"open",4) == 0) ret = open;
            else if (strncmp(buff,"playing",7) == 0) ret = playing;
            else if (strncmp(buff,"paused",6) == 0) ret = paused;
            else if (strncmp(buff,"stopped",7) == 0) ret = stopped;
            else ret = unknown;
            delete [] buff;
            return ret;
        }
};

int main()
{
    MCI mp3("C:\\1.mp3");
    std::cout << mp3.Lenght()/60000.0 << std::endl; // en minutos
    mp3.Play();
    std::cout << "Pulsa F8 para salir" << std::endl;
    while (!GetAsyncKeyState(VK_F8))
    {
        std::cout << "\r" << mp3.Position()/60000.0;
        Sleep(500);
    }
    mp3.Stop();
    return 0;
}

Por si no te das cuanta el tiempo es tratado en milisegundos. También e de decir que no lo he probado todo, puede que haya métodos que no funcionen del todo bien, en fin, si te encuentras con algún error o mejora simplemente comenta.

Comparte o puntua esta publicación ▼

0 comentarios:

Publicar un comentario