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

📄 musiccatalog.cpp

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

    m_catMutex->Release();
    m_bSurpressAddMessages = false;
    if (!m_sigs->empty() && m_context->aps->IsTurnedOn()) 
        m_context->target->AcceptEvent(new Event(INFO_UnsignaturedTracksExist)); 
    return kError_NoErr;
}

void MusicCatalog::StartGeneratingSigs(void)
{
    set<string> *newset = new set<string>;
    set<string>::iterator i = m_sigs->begin();
    for (; i != m_sigs->end(); i++) {
        newset->insert(*i);
    }
    m_context->target->AcceptEvent(new GenerateSignatureEvent(newset));
}

void MusicCatalog::StopGeneratingSigs(void)
{
    m_context->target->AcceptEvent(new Event(CMD_KillSigThread));
}

void MusicCatalog::SetDatabase(const char *path)
{
    if (m_database)
        delete m_database;

    m_database = new Database(path, METADATABASE_VERSION);

    if (!m_database->Working()) {
        delete m_database;
        m_database = NULL;
    }

    if (m_database) {
        //if (m_database->IsUpgraded())
        //    m_context->target->AcceptEvent(new Event(INFO_DatabaseUpgraded));
        RePopulateFromDatabase();
        if (m_timeout == 0)
            PruneDatabase(true, true);
        Sort();
    }
}

typedef struct PruneThreadStruct {
    MusicCatalog *mc;
    Thread *thread;
    bool sendmessages;
} PruneThreadStruct;

void MusicCatalog::PruneDatabase(bool sendmessages, bool spawn)
{
    if (spawn) {
        Thread *thread = Thread::CreateThread();

        if (thread) {
            PruneThreadStruct *pts = new PruneThreadStruct;

            pts->mc = this;
            pts->sendmessages = sendmessages;
            pts->thread = thread;

            thread->Create(prune_thread_function, pts, true);
        }
    }
    else {
        PruneThread(sendmessages);
    }
}

void MusicCatalog::prune_thread_function(void *arg)
{
    PruneThreadStruct *pts = (PruneThreadStruct *)arg;

    pts->mc->PruneThread(pts->sendmessages);

    delete pts->thread;
    delete pts;
}

void MusicCatalog::PruneThread(bool sendmessages)
{
    m_catMutex->Acquire();
    char *key = m_database->NextKey(NULL);
    struct stat st;

    while (key) {
        if (!strncmp("file://", key, 7)) {
            uint32 length = strlen(key) + 1;
            char *filename = new char[length];

            if (IsntError(URLToFilePath(key, filename, &length))) {
                if (-1 == stat(filename, &st)) {
                    if (sendmessages) {
                        Remove(key);
                        key = NULL;
                    }
                    else {
                        m_database->Remove(key);
                        m_trackCount--;
                        key = NULL;
                    }
                }
            }
            delete [] filename;
        }
        key = m_database->NextKey(key);
    }
    m_catMutex->Release();
}

void MusicCatalog::PruneDirectory(string &directory)
{
    m_catMutex->Acquire();

    char *key = m_database->NextKey(NULL);
    struct stat st;
 
    while (key) {
        if (!strncmp("file://", key, 7)) {
            uint32 length = strlen(key) + 1;
            char *filename = new char[length];
            
            if (IsntError(URLToFilePath(key, filename, &length))) {
                if (!strncmp(directory.c_str(), filename, directory.size())) {
                    if (-1 == stat(filename, &st)) {
                        Remove(key);
                        key = NULL;
                    }
                }
            }
            delete [] filename;
        }
        key = m_database->NextKey(key);
    }
    m_catMutex->Release();
}

typedef struct MusicSearchThreadStruct {
    MusicCatalog *mc;
    vector<string> pathList;
    bool bSendMessages;
    Thread *thread;
} MusicSearchThreadStruct;

void MusicCatalog::SearchMusic(vector<string> &pathList, bool bBrowserMessages)
{
    if (!m_database->Working())
        return;

    Thread *thread = Thread::CreateThread();

    if (thread) {
        MusicSearchThreadStruct *mst = new MusicSearchThreadStruct;

        mst->mc = this;
        mst->pathList = pathList;
        mst->thread = thread;
        mst->bSendMessages = bBrowserMessages;

        thread->Create(musicsearch_thread_function, mst, true);
    }
}

void MusicCatalog::StopSearchMusic(void)
{
    m_exit = true;
}

void MusicCatalog::musicsearch_thread_function(void *arg)
{
    MusicSearchThreadStruct *mst = (MusicSearchThreadStruct *)arg;

    mst->mc->m_mutex->Acquire();

    mst->mc->m_exit = false;
    mst->mc->DoSearchPaths(mst->pathList, mst->bSendMessages);

    if (mst->bSendMessages)
        mst->mc->AcceptEvent(new Event(INFO_SearchMusicDone));

    mst->mc->m_mutex->Release();

    delete mst->thread;
    delete mst;
}

void MusicCatalog::DoSearchPaths(vector<string> &pathList, bool bSendMessages)
{
    vector<string>::iterator i;
    
    if (!bSendMessages)
        m_addImmediately = true;

    for(i = pathList.begin(); i != pathList.end(); i++)
        DoSearchMusic((char *)(*i).c_str(), bSendMessages);

    m_addImmediately = false;
}

void MusicCatalog::DoSearchMusic(char *path, bool bSendMessages)
{
    WIN32_FIND_DATA find;
    HANDLE handle;
    string search = path;

#ifndef WIN32
    if (!strcmp(path, "/dev") || !strcmp(path, "/proc"))
        return;
#endif
 
    if (bSendMessages) 
    {
        string info = string("Searching: ") + search;
        m_context->player->AcceptEvent(new BrowserMessageEvent(info));
    }
   
    if (search[search.size() - 1] != DIR_MARKER)
       search.append(DIR_MARKER_STR);

    search.append("*");
#ifdef WIN32
    search.append(".*");
#endif

    handle = FindFirstFile((char *)search.c_str(), &find);

    if (handle != INVALID_HANDLE_VALUE)
    {
        do
        {
            char *fileExt;
#ifndef WIN32
            if (find.dwFileAttributes & FILE_ATTRIBUTE_SYMLINK)
                continue;
#endif
            if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if (!(!strcmp("." , find.cFileName) || !strcmp("..", find.cFileName)))
                {
                    string newDir = path; 
                    if (path[strlen(path) - 1] != DIR_MARKER)
                        newDir.append(DIR_MARKER_STR);
                    newDir.append(find.cFileName);

                    DoSearchMusic((char *)newDir.c_str(), bSendMessages);
                }
            }
            else 
            {
#ifdef WIN32
                string dirtest = path;
                if (path[strlen(path) - 1] != DIR_MARKER)
                    dirtest.append(DIR_MARKER_STR);
                dirtest.append(find.cFileName);

                struct stat stdir;

                stat(dirtest.c_str(), &stdir);
                if (stdir.st_mode & _S_IFDIR) {
                    DoSearchMusic((char *)dirtest.c_str(), bSendMessages);
                    continue;
                }
#endif          
                fileExt = m_context->player->GetExtension(find.cFileName);
                if (fileExt && m_plm->IsSupportedPlaylistFormat(fileExt) && 
                    strcmp("currentlist.m3u", find.cFileName))
                {
                    string file = path;
                    file.append(DIR_MARKER_STR);
                    file.append(find.cFileName);

                    uint32 urlLength = strlen(file.c_str()) + 10;
                    char *url = new char[urlLength];

                    if (IsntError(FilePathToURL(file.c_str(), url, &urlLength)))
                        m_database->Insert(url, "P");

                    if (m_addImmediately)
                        AddPlaylist(url);

                    delete [] url;
                }
                else if (fileExt && 
                         m_context->player->IsSupportedExtension(fileExt))
                {
                    string file = path;
                    file.append(DIR_MARKER_STR);
                    file.append(find.cFileName);

                    char *tempurl = new char[file.length() + 10];
                    uint32 length = file.length() + 10;

                    if (IsError(FilePathToURL(file.c_str(), tempurl, &length)))
                    {
                        delete [] tempurl;
                        delete [] fileExt;

                        continue;
                    }
                   
                    if (!bSendMessages) {
                        MetaData *tdata = ReadMetaDataFromDatabase(tempurl);
                        if (tdata) {
                            delete tdata;
                            delete [] tempurl;
                            delete [] fileExt;

                            continue;
                        }
                    }

                    PlaylistItem *plist = new PlaylistItem(tempurl);
                    m_plm->RetrieveMetaDataNow(plist);

                    MetaData *tempdata = ReadMetaDataFromDatabase(tempurl);
                    if (!tempdata || !m_addImmediately) {
                        MetaData newmdata = (MetaData)plist->GetMetaData();
                        if (tempdata)
                            newmdata.SetGUID(tempdata->GUID());

                        WriteMetaDataToDatabase(tempurl, newmdata);
                    }
                    if (m_addImmediately)
                        AddSong(tempurl);

                    if (tempdata)
                        delete tempdata;
                    delete plist;
                    delete [] tempurl;
                }
                if (fileExt)
                    delete [] fileExt;
            }
        }
        while (FindNextFile(handle, &find) && !m_exit);
        FindClose(handle);
    }
}

void MusicCatalog::WriteMetaDataToDatabase(const char *url, 
                                           const MetaData metadata,
                                           MetadataStorageType type)
{
    if (!m_database->Working())
        return;

    string ost;
    char *num = new char[4096];
    char *temp = new char[1024];
    const char *kDatabaseDelimiter = " ";

    if (type == kTypeStream)
        ost.append("S");
    else
        ost.append("M");
    ost.append(kDatabaseDelimiter);
    ost.append("11");
    ost.append(kDatabaseDelimiter);

    sprintf(num, "%ld%s", (long int)metadata.Artist().size(), kDatabaseDelimiter);
    ost.append(num);
    sprintf(num, "%ld%s", (long int)metadata.Album().size(), kDatabaseDelimiter);
    ost.append(num);
    sprintf(num, "%ld%s", (long int)metadata.Title().size(), kDatabaseDelimiter);
    ost.append(num);
    sprintf(num, "%ld%s", (long int)metadata.Comment().size(), kDatabaseDelimiter);
    ost.append(num);
    sprintf(num, "%ld%s", (long int)metadata.Genre().size(), kDatabaseDelimiter);
    ost.append(num);
    sprintf(temp, "%ld", (long int)metadata.Year());
    sprintf(num, "%ld%s", (long int)strlen(temp), kDatabaseDelimiter);
    ost.append(num);
    sprintf(temp, "%ld", (long int)metadata.Track());
    sprintf(num, "%ld%s", (long int)strlen(temp), kDatabaseDelimiter);
    ost.append(num);
    sprintf(temp, "%ld", (long int)metadata.Time());
    sprintf(num, "%ld%s", (long int)strlen(temp), kDatabaseDelimiter);
    ost.append(num);
    sprintf(temp, "%ld", (long int)metadata.Size());
    sprintf(num, "%ld%s", (long int)strlen(temp), kDatabaseDelimiter);
    ost.append(num);
    sprintf(temp, "%ld", (long int)metadata.PlayCount());
    sprintf(num, "%ld%s", (long int)strlen(temp), kDatabaseDelimiter);
    ost.append(num);
    sprintf(num, "%ld%s", (long int)metadata.GUID().size(), kDatabaseDelimiter);
    ost.append(num);

    ost.append(metadata.Artist());
    ost.append(metadata.Album());
    ost.append(metadata.Title());
    ost.append(metadata.Comment());
    ost.append(metadata.Genre());
    sprintf(temp, "%ld", (long int)metadata.Year());
    ost.append(temp);

⌨️ 快捷键说明

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