player.cpp

来自「这是一个mp3的源代码」· C++ 代码 · 共 1,991 行 · 第 1/4 页

CPP
1,991
字号
/*____________________________________________________________________________
        
        FreeAmp - The Free MP3 Player

        Portions Copyright (C) 1998-1999 EMusic.com

        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program; if not, Write to the Free Software
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        
        $Id: player.cpp,v 1.172 2000/01/20 00:48:45 robert Exp $
____________________________________________________________________________*/

#include <iostream.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h> 
#ifdef WIN32
#include <direct.h>
#define MKDIR(z) mkdir(z)
#else
#define MKDIR(z) mkdir(z, 0755)
#endif

#include "config.h"
#include "event.h"
#include "lmc.h"
#include "player.h"
#include "thread.h"
#include "debug.h"
#include "ui.h"
#include "queue.h"
#include "semaphore.h"
#include "eventdata.h"
#include "registrar.h"
#include "preferences.h"
#include "properties.h"
#include "facontext.h"
#include "log.h"
#include "pmo.h"
#include "utility.h"
#include "downloadmanager.h"

#define DB Debug_v("%s:%d\n", __FILE__, __LINE__);

Player   *Player::m_thePlayer = NULL;

const char *szPlaylistExt = ".M3U";
const char *themeExtension = "fat";

#define SEND_NORMAL_EVENT(e) { Event *ev = new Event(e); GetUIManipLock();    \
                               SendToUI(ev); ReleaseUIManipLock(); delete ev; \
                             }


Player *
Player::
GetPlayer(FAContext *context)
{
    if (m_thePlayer == NULL)
        m_thePlayer = new Player(context);
    return m_thePlayer;
}

Player::
Player(FAContext *context):
EventQueue()
{
    m_context = context;
    m_context->player = this;
    // cout << "Creating player..." << endl;
    m_eventSem = new Semaphore();
    m_eventQueue = new Queue < Event * >();
    // cout << "Created queue" << endl;
    m_eventServiceThread = NULL;
    // cout << "Started event thread" << endl;
    m_uiList = new vector < UserInterface * >;
    // cout << "Created Lists" << endl;
    m_uiManipLock = new Mutex();
    m_lmcMutex = new Mutex();
    m_pmiMutex = new Mutex();
    m_pmoMutex = new Mutex();
    m_uiMutex = new Mutex();
    // cout << "Created mutex" << endl;
    m_imQuitting = 0;
    m_quitWaitingFor = 0;
    m_plm = new PlaylistManager(m_context);
    m_playerState = PlayerState_Stopped;

    m_lmcRegistry = NULL;
    m_pmiRegistry = NULL;
    m_pmoRegistry = NULL;
    m_uiRegistry = NULL;

    m_lmcExtensions = NULL;

    m_browserUI = NULL;
    m_downloadUI = NULL;

    m_pmo = NULL;
    m_lmc = NULL;
    m_ui = NULL;

    m_argUIList = new vector < char *>();

    m_argc = 0;
    m_argv = NULL;
    m_pTermSem = NULL;

    m_didUsage = false;
    m_autoplay = true;

    m_props.RegisterPropertyWatcher("pcm_volume", (PropertyWatcher *) this);

    m_context->plm = m_plm;
    m_context->props = &m_props;
    m_context->target = (EventQueue *) this;

    m_musicCatalog = new MusicCatalog(m_context);
    m_context->catalog = m_musicCatalog;

    // make sure the db dir exists so we have a place to store our 
    // stuff

    char* tempDir = new char[_MAX_PATH];
    uint32 length = _MAX_PATH;
    struct stat st;

    m_context->prefs->GetPrefString(kDatabaseDirPref, tempDir, &length);

    if(-1 == stat(tempDir, &st))
    {
        MKDIR(tempDir);
    }

    string freeampdir = tempDir;
    freeampdir += DIR_MARKER_STR;
    freeampdir += "metadatabase";
    m_musicCatalog->SetDatabase(freeampdir.c_str());

    // make sure the music dir exists so we have a place to store our 
    // stuff

    length = _MAX_PATH;
    m_context->prefs->GetPrefString(kSaveMusicDirPref, tempDir, &length);

    if(-1 == stat(tempDir, &st))
    {
        MKDIR(tempDir);
    }

    delete [] tempDir;
    m_dlm = new DownloadManager(m_context);
    m_context->downloadManager = m_dlm;
}

#define TYPICAL_DELETE(x) /*printf("deleting...\n");*/ if (x) { delete x; x = NULL; }

Player::
~Player()
{
    TYPICAL_DELETE(m_dlm);

    TYPICAL_DELETE(m_pTermSem);

    if(m_argUIList)
    {
        vector<char*>::iterator i = m_argUIList->begin();

        for (; i != m_argUIList->end(); i++)
            delete [] *i; 

        delete m_argUIList;

        m_argUIList = NULL;
    }

    if(m_eventServiceThread)
    {
        m_eventServiceThread->Join();
        delete    m_eventServiceThread;

        m_eventServiceThread = NULL;
    }

    if(m_pmo)
    {
        m_pmo->Pause();
        delete    m_pmo;

        m_pmo = NULL;
    }

    TYPICAL_DELETE(m_eventSem);
    TYPICAL_DELETE(m_eventQueue);

    // Delete CIOs
    if(m_uiList)
    {
        vector<UserInterface *>::iterator i = m_uiList->begin();

        for (; i != m_uiList->end(); i++)
            delete *i; 
        delete m_uiList;

        m_uiList = NULL;
    }

    TYPICAL_DELETE(m_plm);
    TYPICAL_DELETE(m_uiManipLock);
    TYPICAL_DELETE(m_lmcMutex);
    TYPICAL_DELETE(m_pmiMutex);
    TYPICAL_DELETE(m_pmoMutex);
    TYPICAL_DELETE(m_uiMutex);
    TYPICAL_DELETE(m_lmcRegistry);
    TYPICAL_DELETE(m_pmiRegistry);
    TYPICAL_DELETE(m_pmoRegistry);
    TYPICAL_DELETE(m_uiRegistry);
    TYPICAL_DELETE(m_lmcExtensions);
    TYPICAL_DELETE(m_musicCatalog);
}

void      
Player::
SetTerminationSemaphore(Semaphore * pSem)
{
    m_pTermSem = pSem;
}

/*
    return true if parsing was successful, false otherwise. 
*/

typedef char *pchar;

bool      
Player::
SetArgs(int32 argc, char **argv)
{
    bool autoplay = false;
    char* path = new char[_MAX_PATH];
    char* url = new char[_MAX_PATH];

    // remember these guys so we can use them later and elsewhere
    m_argc = argc;
    m_argv = argv;

    m_context->argv = m_argv;
    m_context->argc = m_argc;

    // now parse them and pull out any args we know about
    for (int32 i = 1; i < argc; i++)
    {
        char* arg = argv[i];

        // is this an option?
        if(arg[0] == '-' 
#ifdef WIN32
        	|| arg[0] == '/'
#endif   
			)
        {
            switch(arg[1])
            {
                // print help
                case 'h':
                case 'H':
                case '-':
                    if(!strcasecmp(arg + 1, "help") || !strcasecmp(arg + 2, "help"))
                    {
                        Usage(argv[0]);
                        AcceptEvent(new Event(CMD_QuitPlayer));
                        return true;
                    }
                    break;

                // autoplay
                case 'p':
                case 'P':
                    if(!strcasecmp(arg + 1, "play"))
                        autoplay = true;

                // save streams
                // shuffle
                case 's':
                case 'S':
                    if(!strcasecmp(arg + 1, "save"))
		                m_context->argFlags |= FAC_ARGFLAGS_SAVE_STREAMS;
                    else if(!strcasecmp(arg + 1, "shuffle"))
                        m_plm->SetShuffleMode(true);

                    break;

                // set UIs
                case 'u':
                case 'U':
                {
                    if(arg[2] == 'i' || arg[2] == 'I')
                    {
                        char* argUI = NULL;
                        
                        i++;
                        if(i >= argc)
                        {
                            Usage(argv[0]);
                            AcceptEvent(new Event(CMD_QuitPlayer));
                            return false;
                        }

                        arg = argv[i];

                        argUI = new char[strlen(arg) + 1];

                        strcpy(argUI, arg);
                        
                        m_argUIList->push_back(argUI);
                    }

                    break;
                }

                default:
                    break;

            }
        }
        else
        {
            // is this a URL we know how to handle
            if( !strncasecmp(arg, "http://", 7) || 
                !strncasecmp(arg, "rtp://", 6))
            {
                m_plm->AddItem(arg);
            }
            else
            {
#ifdef WIN32
                strcpy(path, arg);

                HANDLE handle;
                WIN32_FIND_DATA data;
        
                handle = FindFirstFile(arg, &data);

                // find long filename for item and
                // expand wildcards...
                if(handle != INVALID_HANDLE_VALUE)
                {
                    do
                    {
                        char* cp = NULL;
                    
                        cp = strrchr(path, '\\');

                        if(cp)
                            cp++;
                        else 
                            cp = path;

                        strcpy(cp, data.cFileName);


                        // make sure we have an absolute path
                        ResolvePath(&path);

                        // format this path as a URL
                        uint32 length = _MAX_PATH;
                        FilePathToURL(path, url, &length);

                        // who needs to get this, plm or dlm?
                        bool giveToDLM = false;
                        bool giveToTheme = false;
                        char* extension = NULL;

                        extension = strrchr(url, '.');
                        if(extension)
                        {
                            DownloadFormatInfo dlfi;
                            uint32 i = 0;

                            extension++;

                            while(IsntError(m_dlm->GetSupportedDownloadFormats(&dlfi, i++)))
                            {
                                if(!strcasecmp(extension, dlfi.GetExtension()))
                                {
                                    giveToDLM = true;
                                    break;
                                }
                            }
                            if (strcasecmp(extension, themeExtension) == 0)
                                giveToTheme = true; 
                        }


                        if(giveToDLM)
                            m_dlm->ReadDownloadFile(url);
                        else
                        if(giveToTheme)
                        {
                            char szSavedTheme[_MAX_PATH], szNewTheme[_MAX_PATH];
                            uint32 iLen = _MAX_PATH;   

                            m_context->prefs->GetPrefString(kThemePathPref, 
                                 szSavedTheme, &iLen);
                            iLen = _MAX_PATH;   
                            URLToFilePath(url, szNewTheme, &iLen); 
                            m_context->prefs->SetPrefString(kThemePathPref, 
                               szNewTheme);

                            AcceptEvent(new LoadThemeEvent(url, szSavedTheme));
                        }
                        else 
                            m_plm->AddItem(url); 

                    }while(FindNextFile(handle, &data));
                   
                    FindClose(handle);
                }
                else // is this a URL we know how to handle ?
                {
                    // file not found? don't add it...
                    continue;
                }
#else
                strcpy(path, arg);
                
                //printf("Path: %s\r\n", path);
               
                // make sure we have an absolute path
                ResolvePath(&path);
               
                //printf("Resolved: %s\r\n", path);

                // format this path as a URL
                uint32 length = _MAX_PATH;
                FilePathToURL(path, url, &length);
            
                //printf("URL: %s\r\n", url);

                // who needs to get this, plm or dlm?
                bool giveToDLM = false;
                bool giveToTheme = false;
                char* extension = NULL;

                extension = strrchr(url, '.');

                if(extension)
                {
                    DownloadFormatInfo dlfi;
                    uint32 i = 0;

                    extension++;

                    while(IsntError(m_dlm->GetSupportedDownloadFormats(&dlfi, i++)))
                    {
                        if(!strcasecmp(extension, dlfi.GetExtension()))
                        {
                            giveToDLM = true;
                            break;
                        }
                    }
                    if (strcasecmp(extension, themeExtension) == 0)
                        giveToTheme = true; 
                }

                if (giveToDLM) 
                    m_dlm->ReadDownloadFile(url);
                else if (giveToTheme)
                {
                    char szSavedTheme[_MAX_PATH], szNewTheme[_MAX_PATH];
                    uint32 iLen = _MAX_PATH;   

                    m_context->prefs->GetPrefString(kThemePathPref, 
                                                    szSavedTheme, &iLen);
                    iLen = _MAX_PATH;   
                    URLToFilePath(url, szNewTheme, &iLen); 
                    m_context->prefs->SetPrefString(kThemePathPref, szNewTheme);

                    AcceptEvent(new LoadThemeEvent(url, szSavedTheme));
                }
                else 
                {
                    m_plm->AddItem(url); 
               	}	
#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?