⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 musiccatalog.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*____________________________________________________________________________

        FreeAmp - The Free MP3 Player

        Portions Copyright (C) 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: musiccatalog.cpp,v 1.103 2001/03/05 21:54:47 ijr Exp $
____________________________________________________________________________*/

// The debugger can't handle symbols more than 255 characters long.
// STL often creates symbols longer than that.
// When symbols are longer than 255 characters, the warning is disabled.
#ifdef WIN32
#pragma warning(disable:4786) 
#endif

#include "config.h"

#include <sys/stat.h>

#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#include "win32impl.h"
#endif

#include <string>
#include <algorithm>

using namespace std;

#include "musiccatalog.h"
#include "player.h"
#include "utility.h"
#include "pmo.h"
#include "debug.h"

#define METADATABASE_VERSION 1
#define DATABASE_SUB_VERSION 3

MusicCatalog::MusicCatalog(FAContext *context, char *databasepath)
{
    m_database = NULL;
    m_context = context;
    m_plm = context->plm;
    m_mutex = new Mutex();
    m_catMutex = new Mutex();
    m_timerMutex = new Mutex();
    m_MBLookupLock = new Mutex();
    m_inUpdateSong = false;
    m_addImmediately = false;
    m_bSurpressAddMessages = false;
    m_trackCount = 0;
    m_artistList = new vector<ArtistList *>;
    m_unsorted = new vector<PlaylistItem *>;
    m_playlists = new vector<string>;
    m_streams = new vector<PlaylistItem *>;
    m_sigs = new set<string>;
    m_guidTable = new multimap<string, string, less<string> >;
    m_MBRequests = new vector<pair<string, string> >;
    m_watchTimer = NULL;

    m_killGUIDs = false;

    m_killMBThread = false;
    m_MBLookupThreadActive = false;
    m_pendingMBLookups = 0;
    m_timeout = 0;
    context->prefs->GetPrefInt32(kWatchThisDirTimeoutPref, &m_timeout);

    if (databasepath)
        SetDatabase(databasepath);
}

void MusicCatalog::StartTimer(void)
{
    if (m_timeout > 0) {
        WatchTimer();
        m_context->timerManager->StartTimer(&m_watchTimer, watch_timer,
                                            m_timeout, this);
    }
}

MusicCatalog::~MusicCatalog()
{
    m_killMBThread = true;
    while (m_MBLookupThreadActive)
        usleep(50);

    ClearCatalog();
    StopSearchMusic();

    m_mutex->Acquire();
    m_catMutex->Acquire();
    m_timerMutex->Acquire();

    if(m_watchTimer)
        m_context->timerManager->StopTimer(m_watchTimer);

    delete m_artistList;
    delete m_unsorted;
    delete m_streams;

    delete m_sigs;

    if (m_database)
        delete m_database;

    delete m_playlists;
    delete m_mutex;
    delete m_catMutex;
    delete m_timerMutex;
    delete m_guidTable;
}

string MusicCatalog::GetFilename(const string &strGUID)
{
    if ((!m_guidTable) || (m_guidTable->size() == 0))
        return "";
    
    multimap<string, string, less<string> >::iterator i;
    i = m_guidTable->find(strGUID);

    if (i != m_guidTable->end())
        return (*i).second;
    return "";
}

class comp_catalog {
  public:
      bool operator()(PlaylistItem *a, PlaylistItem *b)
      {
          if (a->GetMetaData().Track() == b->GetMetaData().Track())
             // sort alphabetically...
             return (a->GetMetaData().Title() < b->GetMetaData().Title());
          return (a->GetMetaData().Track() < b->GetMetaData().Track());
      }
      bool operator()(AlbumList *a, AlbumList *b)
      {
          return (a->name < b->name);
      }
      bool operator()(ArtistList *a, ArtistList *b)
      {
          return (a->name < b->name);
      }
};

void MusicCatalog::Sort(void)
{
    m_catMutex->Acquire();
    // Sort the playlists...
    sort(m_playlists->begin(), m_playlists->end());

    // Sort the uncategorized tracks
    sort(m_unsorted->begin(), m_unsorted->end(), comp_catalog());

    // Sort the rest o the junk
    vector<ArtistList *>::iterator i = m_artistList->begin();
    for (; i != m_artistList->end(); i++) {
        vector<AlbumList *>::iterator j = (*i)->m_albumList->begin();
        for (; j != (*i)->m_albumList->end(); j++) {
            sort((*j)->m_trackList->begin(), (*j)->m_trackList->end(), 
                 comp_catalog());
        }
        sort((*i)->m_albumList->begin(), (*i)->m_albumList->end(), 
             comp_catalog());
    }
    sort(m_artistList->begin(), m_artistList->end(), comp_catalog());

    // Sort the streams
    sort(m_streams->begin(), m_streams->end(), comp_catalog());

    m_catMutex->Release();
}

Error MusicCatalog::RemovePlaylist(const char *url)
{
    assert(url);

    if (!m_database->Working())
        return kError_DatabaseNotWorking;

    char *data = m_database->Value(url);

    if (!data)
        return kError_ItemNotFound;

    delete [] data;
    m_database->Remove(url);

    m_catMutex->Acquire();

    vector<string>::iterator i = m_playlists->begin();
    for (; i != m_playlists->end(); i++)
         if ((*i) == url) {
             string tempstr = url;
             if (tempstr.find("currentlist.m3u") >= tempstr.length()) {
                 string sUrl = url; 
                 m_context->target->AcceptEvent(new MusicCatalogPlaylistRemovedEvent(sUrl));
                 m_playlists->erase(i);
             }
             m_catMutex->Release();
             return kError_NoErr;
         }   

    m_catMutex->Release();
    return kError_ItemNotFound;
}


Error MusicCatalog::AddPlaylist(const char *url)
{
    assert(url);

    if (!m_database->Working())
        return kError_DatabaseNotWorking;
    
    char *data = m_database->Value(url);
    if (!data) 
        m_database->Insert(url, "P");
    else 
        delete [] data;

    bool found = false;
    m_catMutex->Acquire();
    vector<string>::iterator i = m_playlists->begin();
    for (; i != m_playlists->end(); i++)
         if ((*i) == url)
             found = true;
    
    if (!found) {
        string tempstr = url;
        if (tempstr.find("currentlist.m3u") < tempstr.length()) 
            m_playlists->insert(m_playlists->begin(), url);
        else
            m_playlists->push_back(url);

        string sUrl = url;
        m_context->target->AcceptEvent(new MusicCatalogPlaylistAddedEvent(sUrl));
        m_catMutex->Release();
        return kError_NoErr;
    }

    m_catMutex->Release();
    return kError_DuplicateItem;
}

Error MusicCatalog::RemoveStream(const char *url)
{
    assert(url);

    if (!m_database->Working())
        return kError_DatabaseNotWorking;

    MetaData *meta = ReadMetaDataFromDatabase(url);
    if (!meta)
        return kError_ItemNotFound;

    string strGUID = meta->GUID();

    m_database->Remove(url);

    m_catMutex->Acquire();
    
    vector<PlaylistItem *>::iterator i = m_streams->begin();
    for (; i != m_streams->end(); i++)
         if ((*i)->URL() == url) {
             m_context->target->AcceptEvent(new MusicCatalogStreamRemovedEvent(*i));
             delete (*i);
             m_streams->erase(i);
             break;
         }

    if ((strGUID.size() != 0) && (m_guidTable->size() != 0)) {
        multimap<string, string, less<string> >::iterator i;
        i = m_guidTable->find(strGUID);
        while ((i != m_guidTable->end()) && ((*i).first == strGUID)) {
            if ((*i).second == url) {
                m_guidTable->erase(i);
                break;
            }
            i++;
        }
    }

    m_catMutex->Release();

    delete meta;
    return kError_NoErr;
}

PlaylistItem *MusicCatalog::GetPlaylistItemFromURL(const char *url)
{
    assert(url);
    PlaylistItem *retitem = NULL;

    if (!m_database->Working())
        return retitem;

    MetaData *meta = ReadMetaDataFromDatabase(url);
    if (!meta)
        return retitem;

    m_catMutex->Acquire();
    if ((meta->Artist().size() == 0) || (meta->Artist() == " ")) {
        vector<PlaylistItem *>::iterator i = m_unsorted->begin();
        for (; i != m_unsorted->end(); i++)
            if ((*i)->URL() == url)
            {
                retitem = *i;
                break;
            }
    }
    else 
    {
        vector<ArtistList *>::iterator    i;
        vector<AlbumList *>              *alList;
        vector<AlbumList *>::iterator     j;
        vector<PlaylistItem *>           *trList;
        vector<PlaylistItem *>::iterator  k;
        bool                              found = false;

        i = m_artistList->begin();
        for (; i != m_artistList->end() && !found; i++)
        {
            if (CaseCompare(meta->Artist(),(*i)->name))
            {
                alList = (*i)->m_albumList;
                j = alList->begin();
                for (; j != alList->end() && !found; j++)
                {
                    if (CaseCompare(meta->Album(),(*j)->name))
                    {
                        trList = (*j)->m_trackList;
                        k = trList->begin();
                        for (; k != trList->end() && !found; k++)
                            if (url == (*k)->URL())
                            {
                                retitem = *k;
                                found = true;
                                break;
                            }

                     } 
                }
            }
        }
    }
 
    delete meta;

    m_catMutex->Release();
    return retitem;
}

Error MusicCatalog::RemoveSong(const char *url)
{
    assert(url);

    if (!m_database->Working())
        return kError_DatabaseNotWorking;

    MetaData *meta = ReadMetaDataFromDatabase(url);
    if (!meta)
        return kError_ItemNotFound;

    string strGUID = meta->GUID();

    m_database->Remove(url);

    m_catMutex->Acquire();
    if ((meta->Artist().size() == 0) || (meta->Artist() == " ")) {
        vector<PlaylistItem *>::iterator i = m_unsorted->begin();
        for (; i != m_unsorted->end(); i++)
            if ((*i)->URL() == url)
            {
                AcceptEvent(new MusicCatalogTrackRemovedEvent(*i, NULL, NULL));
                m_unsorted->erase(i);
                m_trackCount--;
                break;
            }
    }

⌨️ 快捷键说明

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