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

📄 musiccatalog.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    sprintf(temp, "%ld", (long int)metadata.Track());
    ost.append(temp);
    sprintf(temp, "%ld", (long int)metadata.Time());
    ost.append(temp);
    sprintf(temp, "%ld", (long int)metadata.Size());
    ost.append(temp);
    sprintf(temp, "%ld", (long int)metadata.PlayCount());
    ost.append(temp);
    ost.append(metadata.GUID());
    ost.append("\0");

    if (metadata.GUID().size() > 0)
        if (GetFilename(metadata.GUID()).size() == 0) 
            m_guidTable->insert(multimap<string, string, less<string> >
                                ::value_type(metadata.GUID().c_str(), url));
         
    m_database->Insert(url, (char *)ost.c_str());

    delete [] num;
    delete [] temp;
}

MetaData *MusicCatalog::ReadMetaDataFromDatabase(const char *url)
{
    if (!m_database->Working())
        return NULL;

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

    if (!dbasedata)
        return NULL;

    MetaData *metadata = new MetaData();
    char *value = dbasedata + 2;

    uint32 numFields = 0;
    int offset = 0;

    sscanf(value, "%lu%n", (long unsigned int *)&numFields, &offset);
    uint32* fieldLength =  new uint32[numFields];

    int temp;

    for(uint32 i = 0; i < numFields; i++)
    {
        sscanf(value + offset, " %lu %n", (long unsigned int *)&fieldLength[i],
	                                  &temp);

        if (i == numFields - 1) {
            char intholder[10];
            sprintf(intholder, "%lu", (long unsigned int)fieldLength[i]);
            offset += strlen(intholder) + 1;
        }
        else
            offset += temp;
    }

    string data = value;
    data.erase(0, offset);

    uint32 count = 0;
    string substring;

    for(uint32 j = 0; j < numFields; j++)
    {
        if (fieldLength[j] == 0) 
            continue;

        substring = data.substr(count, fieldLength[j]);

        switch(j)
        {
            case 0:
                metadata->SetArtist(substring);
                break;
            case 1:
                metadata->SetAlbum(substring);
                break;
            case 2:
                metadata->SetTitle(substring);
                break;
            case 3:
                metadata->SetComment(substring);
                break;
            case 4:
                metadata->SetGenre(substring);
                break;
            case 5:
                metadata->SetYear(atoi(substring.c_str()));
                break;
            case 6:
                metadata->SetTrack(atoi(substring.c_str()));
                break;
            case 7:
                metadata->SetTime(atoi(substring.c_str()));
                break;
            case 8:
                metadata->SetSize(atoi(substring.c_str()));
                break;
            case 9:
                metadata->SetPlayCount(atoi(substring.c_str()));
                break;
            case 10: 
                metadata->SetGUID(substring);
                break;
            default:
                break;

        }

        count += fieldLength[j];
    }

    delete [] fieldLength;
    delete [] dbasedata;

    if (metadata->GUID().size() > 0)
        if (GetFilename(metadata->GUID()).size() == 0)
            m_guidTable->insert(multimap<string, string, less<string> >
                                ::value_type(metadata->GUID().c_str(), url));

    return metadata;
}

typedef struct MBLookupThreadStruct
{
    MusicCatalog *mc;
    Thread *thread;
} MBLookupTreadStruct;

Error MusicCatalog::AcceptEvent(Event *e)
{
    switch (e->Type()) {
        case INFO_MusicCatalogTrackRemoved: {
            if (m_inUpdateSong) {
                MusicCatalogTrackRemovedEvent *mctr = 
                                             (MusicCatalogTrackRemovedEvent *)e;
                m_oldItem = (PlaylistItem *)mctr->Item();
                m_oldArtist = (ArtistList *)mctr->Artist();
                m_oldAlbum = (AlbumList *)mctr->Album();
     
                delete e;
            }
            else 
                m_context->target->AcceptEvent(e);
            break; }
        case INFO_MusicCatalogTrackAdded: {
            if (m_inUpdateSong) {
                MusicCatalogTrackAddedEvent *mcta =
                                             (MusicCatalogTrackAddedEvent *)e;
                m_newItem = (PlaylistItem *)mcta->Item();
                m_newArtist = (ArtistList *)mcta->Artist();
                m_newAlbum = (AlbumList *)mcta->Album();

                delete e;
            }
            else if (!m_bSurpressAddMessages)
                m_context->target->AcceptEvent(e);
            else
                delete e;
            break; }
        case INFO_SearchMusicDone: {
            m_context->target->AcceptEvent(new Event(INFO_MusicCatalogRegenerating));
            m_database->Sync();
            string info = "Pruning the Music Catalog Database...";
            m_context->target->AcceptEvent(new BrowserMessageEvent(info));
            PruneDatabase();
            info = "Regenerating the Music Catalog Database...";
            m_context->target->AcceptEvent(new BrowserMessageEvent(info));
            RePopulateFromDatabase();
            info = "Sorting the Music Catalog Database...";
            m_context->target->AcceptEvent(new BrowserMessageEvent(info));
            Sort();
            m_context->target->AcceptEvent(new Event(INFO_SearchMusicDone));
            m_context->target->AcceptEvent(new Event(INFO_MusicCatalogDoneRegenerating));
            delete e;
            break;
        }
        case INFO_PrefsChanged: {
            int32 watchtimeout = 0;
            m_context->prefs->GetPrefInt32(kWatchThisDirTimeoutPref, &watchtimeout);
            if (m_timeout != watchtimeout) {
                m_timeout = watchtimeout;
                if (m_timeout != 0) 
                    m_context->timerManager->SetTimer(m_watchTimer, m_timeout);
                else 
                    m_context->timerManager->StopTimer(m_watchTimer);
            }
            break;
        }
        case INFO_AudioSignatureFailed: {
            AudioSignatureFailedEvent *asfe = (AudioSignatureFailedEvent *)e;
            m_sigs->erase(asfe->Url());

            uint32 length = asfe->Url().size() + 20;
            char *curl = new char[length];
            FilePathToURL(asfe->Url().c_str(), curl, &length);

            string url = curl;
            delete [] curl;
       
            m_sigs->erase(url);

            MetaData *data = ReadMetaDataFromDatabase(url.c_str());
            if (!data)
                data = new MetaData;

            data->SetGUID("BAD_MP3         ");

            WriteMetaDataToDatabase(url.c_str(), (*data));
            m_database->Sync();

            PlaylistItem *plitem = GetPlaylistItemFromURL(url.c_str());
            if (plitem) {
                plitem->SetMetaData(data);
                UpdateSong(plitem);
                m_plm->UpdateTrackMetaData(plitem, false);
            }

            delete data;
            break;
        }   
        case INFO_AudioSignatureGenerated: {
            AudioSignatureGeneratedEvent *asge = 
                                     (AudioSignatureGeneratedEvent *)e;

            m_sigs->erase(asge->Url());

            uint32 length = asge->Url().size() + 20;
            char *curl = new char[length];
            FilePathToURL(asge->Url().c_str(), curl, &length);

            string url = curl;
            delete [] curl;

            m_sigs->erase(url);

            pair<string, string> lookup;
            lookup = make_pair(url, asge->GUID());

            m_MBLookupLock->Acquire();

            m_MBRequests->push_back(lookup);

            if (!m_MBLookupThreadActive)
            {
                Thread *thread = Thread::CreateThread();

                if (thread) {
                    MBLookupThreadStruct *mlts = new MBLookupThreadStruct;

                    mlts->mc = this;
                    mlts->thread = thread;

                    thread->Create(mb_lookup_thread, mlts, true);
                }
            }

            m_MBLookupLock->Release();
            break; 
        }
    }
    return kError_NoErr; 
}

void MusicCatalog::mb_lookup_thread(void *arg)
{
    MBLookupThreadStruct *data = (MBLookupThreadStruct *)arg;

    data->mc->MBLookupThread();

    delete data->thread;
    delete data;
}

void MusicCatalog::MBLookupThread(void)
{
    m_MBLookupThreadActive = true;

    while (true)
    {
        if (m_killMBThread)
            break;

        m_MBLookupLock->Acquire();
        m_pendingMBLookups = m_MBRequests->size();
        m_MBLookupLock->Release();

        if (m_pendingMBLookups <= 0)
            break;

        pair<string, string> lookup;
        m_MBLookupLock->Acquire();
        lookup = (*m_MBRequests)[0];
        m_MBRequests->erase(m_MBRequests->begin());
        m_MBLookupLock->Release();

        DoMBLookup(lookup.first, lookup.second);
    }

    if (m_pendingMBLookups == 0 && m_sigs->size() == 0)
    {
        string message = "Signaturing Has Completed.";
        m_context->target->AcceptEvent(new BrowserMessageEvent(message));
    }

    m_MBLookupThreadActive = false;
}

void MusicCatalog::DoMBLookup(const string &url, const string &GUID)
{
    if (GUID != "") {
        MetaData *data = ReadMetaDataFromDatabase(url.c_str());

        if (!data)
            data = new MetaData;

        if (data->GUID() != "") {
            if (strncmp(data->GUID().c_str(), GUID.c_str(), 16))
                cout << "ERROR! " << url << " has 2 GUIDs!\n";
        }
        data->SetGUID(GUID);

        FAMetaUnit faTemp(data, url.c_str());
        int nRes = m_context->aps->APSFillMetaData(&faTemp);
        if (nRes == 0)
            faTemp.GetMetaData(data);

        WriteMetaDataToDatabase(url.c_str(), (*data));
        m_database->Sync();

        PlaylistItem *plitem = GetPlaylistItemFromURL(url.c_str());
        if (plitem) {
            plitem->SetMetaData(data);
            UpdateSong(plitem);
            m_plm->UpdateTrackMetaData(plitem, false);
        }

        delete data;
    }
    else {
        cerr << "Signaturing Failure for :\n " << url << "\n"
             << "failed.  Are you connected to the internet?  Do you need to\n"
             << "set up a proxy?\n";
    }
}

void MusicCatalog::watch_timer(void *arg) 
{
    MusicCatalog *cat = (MusicCatalog*)arg;
    cat->WatchTimer();
}

void MusicCatalog::WatchTimer(void)
{
    bool welcome;
    m_context->prefs->GetPrefBoolean(kWelcomePref, &welcome);
    if (welcome)
        return;

#ifndef DEBUG_MUTEXES
    if (!m_timerMutex->Acquire(0)) {
#else
    if (!m_timerMutex->__Acquire(__FILE__, __LINE__, 0)) {
#endif
        return;
    }
    char *watchDir = new char[_MAX_PATH];
    uint32 length = _MAX_PATH;

    m_context->prefs->GetPrefString(kWatchThisDirectoryPref, watchDir, &length);

    vector<string> searchPaths;

    char *temp = strtok(watchDir, ";");
    do {
        string dir = temp;
        searchPaths.push_back(dir);
        PruneDirectory(dir);
    } while ((temp = strtok(NULL, ";")));

    unsigned int numsigs = 0;
    if (m_sigs)
        numsigs = m_sigs->size();
    SearchMusic(searchPaths, false);

    if (m_sigs && (m_sigs->size() > numsigs) && m_context->aps->IsTurnedOn())
    {
        m_context->target->AcceptEvent(new Event(CMD_KillSigThread));
        m_context->target->AcceptEvent(new Event(INFO_UnsignaturedTracksExist));
    }

    delete [] watchDir;

    m_timerMutex->Release();
}

⌨️ 快捷键说明

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