📄 musiccatalog.cpp
字号:
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 + -