![]() |
Mixxx
|
00001 /*************************************************************************** 00002 trackinfoobject.cpp - description 00003 ------------------- 00004 begin : 10 02 2003 00005 copyright : (C) 2003 by Tue & Ken Haste Andersen 00006 email : haste@diku.dk 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00018 #include <QDomNode> 00019 #include <QDomDocument> 00020 #include <QDomElement> 00021 #include <QFileInfo> 00022 #include <QMutexLocker> 00023 #include <QString> 00024 #include <QtDebug> 00025 00026 #include "trackinfoobject.h" 00027 00028 #include "soundsourceproxy.h" 00029 #include "xmlparse.h" 00030 #include "controlobject.h" 00031 00032 #include "mixxxutils.cpp" 00033 00034 TrackInfoObject::TrackInfoObject(const QString sLocation, bool parseHeader) 00035 : m_qMutex(QMutex::Recursive) { 00036 QFileInfo fileInfo(sLocation); 00037 populateLocation(fileInfo); 00038 initialize(parseHeader); 00039 } 00040 00041 TrackInfoObject::TrackInfoObject(QFileInfo& fileInfo, bool parseHeader) 00042 : m_qMutex(QMutex::Recursive) { 00043 populateLocation(fileInfo); 00044 initialize(parseHeader); 00045 } 00046 00047 TrackInfoObject::TrackInfoObject(const QDomNode &nodeHeader) 00048 : m_qMutex(QMutex::Recursive) { 00049 m_sFilename = XmlParse::selectNodeQString(nodeHeader, "Filename"); 00050 m_sLocation = XmlParse::selectNodeQString(nodeHeader, "Filepath") + "/" + m_sFilename; 00051 QString create_date; 00052 00053 // We don't call initialize() here because it would end up calling parse() 00054 // on the file. Plus those initializations weren't done before, so it might 00055 // cause subtle bugs. This constructor is only used for legacy importing so 00056 // I'm not going to do it. rryan 6/2010 00057 00058 // Check the status of the file on disk. 00059 QFileInfo fileInfo(m_sLocation); 00060 populateLocation(fileInfo); 00061 00062 m_sTitle = XmlParse::selectNodeQString(nodeHeader, "Title"); 00063 m_sArtist = XmlParse::selectNodeQString(nodeHeader, "Artist"); 00064 m_sType = XmlParse::selectNodeQString(nodeHeader, "Type"); 00065 m_sComment = XmlParse::selectNodeQString(nodeHeader, "Comment"); 00066 m_iDuration = XmlParse::selectNodeQString(nodeHeader, "Duration").toInt(); 00067 m_iSampleRate = XmlParse::selectNodeQString(nodeHeader, "SampleRate").toInt(); 00068 m_iChannels = XmlParse::selectNodeQString(nodeHeader, "Channels").toInt(); 00069 m_iBitrate = XmlParse::selectNodeQString(nodeHeader, "Bitrate").toInt(); 00070 m_iLength = XmlParse::selectNodeQString(nodeHeader, "Length").toInt(); 00071 m_iTimesPlayed = XmlParse::selectNodeQString(nodeHeader, "TimesPlayed").toInt(); 00072 m_fReplayGain = XmlParse::selectNodeQString(nodeHeader, "replaygain").toFloat(); 00073 m_fBpm = XmlParse::selectNodeQString(nodeHeader, "Bpm").toFloat(); 00074 m_bBpmConfirm = XmlParse::selectNodeQString(nodeHeader, "BpmConfirm").toInt(); 00075 m_fBeatFirst = XmlParse::selectNodeQString(nodeHeader, "BeatFirst").toFloat(); 00076 m_bHeaderParsed = false; 00077 create_date = XmlParse::selectNodeQString(nodeHeader, "CreateDate"); 00078 if (create_date == "") 00079 m_dCreateDate = fileInfo.created(); 00080 else 00081 m_dCreateDate = QDateTime::fromString(create_date); 00082 00083 // Mixxx <1.8 recorded track IDs in mixxxtrack.xml, but we are going to 00084 // ignore those. Tracks will get a new ID from the database. 00085 //m_iId = XmlParse::selectNodeQString(nodeHeader, "Id").toInt(); 00086 m_iId = -1; 00087 00088 m_fCuePoint = XmlParse::selectNodeQString(nodeHeader, "CuePoint").toFloat(); 00089 m_bPlayed = false; 00090 00091 m_pVisualWave = 0; 00092 m_dVisualResampleRate = 0; 00093 00094 //m_pWave = XmlParse::selectNodeHexCharArray(nodeHeader, QString("WaveSummaryHex")); 00095 00096 m_bIsValid = true; 00097 00098 m_bDirty = false; 00099 m_bLocationChanged = false; 00100 } 00101 00102 void TrackInfoObject::populateLocation(QFileInfo& fileInfo) { 00103 m_sFilename = fileInfo.fileName(); 00104 m_sLocation = fileInfo.absoluteFilePath(); 00105 m_sDirectory = fileInfo.absolutePath(); 00106 m_iLength = fileInfo.size(); 00107 m_bExists = fileInfo.exists(); 00108 } 00109 00110 void TrackInfoObject::initialize(bool parseHeader) { 00111 m_bDirty = false; 00112 m_bLocationChanged = false; 00113 00114 m_sArtist = ""; 00115 m_sTitle = ""; 00116 m_sType= ""; 00117 m_sComment = ""; 00118 m_sYear = ""; 00119 m_sURL = ""; 00120 m_iDuration = 0; 00121 m_iBitrate = 0; 00122 m_iTimesPlayed = 0; 00123 m_bPlayed = false; 00124 m_fBpm = 0.; 00125 m_fReplayGain = 0.; 00126 m_bBpmConfirm = false; 00127 m_bIsValid = false; 00128 m_bHeaderParsed = false; 00129 m_fBeatFirst = -1.; 00130 m_iId = -1; 00131 m_pVisualWave = 0; 00132 m_iSampleRate = 0; 00133 m_iChannels = 0; 00134 m_fCuePoint = 0.0f; 00135 m_dVisualResampleRate = 0; 00136 m_dCreateDate = m_dateAdded = QDateTime::currentDateTime(); 00137 m_Rating = 0; 00138 m_key = ""; 00139 00140 // parse() parses the metadata from file. This is not a quick operation! 00141 if (parseHeader) { 00142 parse(); 00143 } 00144 } 00145 00146 TrackInfoObject::~TrackInfoObject() { 00147 //qDebug() << "~TrackInfoObject()" << m_iId << getInfo(); 00148 } 00149 00150 void TrackInfoObject::doSave() { 00151 //qDebug() << "TIO::doSave()" << getInfo(); 00152 emit(save(this)); 00153 } 00154 00155 bool TrackInfoObject::isValid() const { 00156 QMutexLocker lock(&m_qMutex); 00157 return m_bIsValid; 00158 } 00159 00160 /* 00161 Writes information about the track to the xml file: 00162 */ 00163 void TrackInfoObject::writeToXML( QDomDocument &doc, QDomElement &header ) 00164 { 00165 QMutexLocker lock(&m_qMutex); 00166 00167 QString create_date; 00168 XmlParse::addElement( doc, header, "Filename", m_sFilename ); 00169 //XmlParse::addElement( doc, header, "Filepath", m_sFilepath ); 00170 XmlParse::addElement( doc, header, "Title", m_sTitle ); 00171 XmlParse::addElement( doc, header, "Artist", m_sArtist ); 00172 XmlParse::addElement( doc, header, "Type", m_sType ); 00173 XmlParse::addElement( doc, header, "Comment", m_sComment); 00174 XmlParse::addElement( doc, header, "Duration", QString("%1").arg(m_iDuration)); 00175 XmlParse::addElement( doc, header, "SampleRate", QString("%1").arg(m_iSampleRate)); 00176 XmlParse::addElement( doc, header, "Channels", QString("%1").arg(m_iChannels)); 00177 XmlParse::addElement( doc, header, "Bitrate", QString("%1").arg(m_iBitrate)); 00178 XmlParse::addElement( doc, header, "Length", QString("%1").arg(m_iLength) ); 00179 XmlParse::addElement( doc, header, "TimesPlayed", QString("%1").arg(m_iTimesPlayed) ); 00180 XmlParse::addElement( doc, header, "replaygain", QString("%1").arg(m_fReplayGain) ); 00181 XmlParse::addElement( doc, header, "Bpm", QString("%1").arg(m_fBpm) ); 00182 XmlParse::addElement( doc, header, "BpmConfirm", QString("%1").arg(m_bBpmConfirm) ); 00183 XmlParse::addElement( doc, header, "BeatFirst", QString("%1").arg(m_fBeatFirst) ); 00184 XmlParse::addElement( doc, header, "Id", QString("%1").arg(m_iId) ); 00185 XmlParse::addElement( doc, header, "CuePoint", QString::number(m_fCuePoint) ); 00186 XmlParse::addElement( doc, header, "CreateDate", m_dCreateDate.toString() ); 00187 //if (m_pWave) { 00188 //XmlParse::addHexElement(doc, header, "WaveSummaryHex", m_pWave); 00189 //} 00190 00191 } 00192 00193 static void doNothing(TrackInfoObject* pTrack) {} 00194 00195 int TrackInfoObject::parse() 00196 { 00197 // Add basic information derived from the filename: 00198 parseFilename(); 00199 00200 // Parse the using information stored in the sound file 00201 bool result = SoundSourceProxy::ParseHeader(this); 00202 m_bIsValid = result == OK; 00203 return result; 00204 } 00205 00206 00207 void TrackInfoObject::parseFilename() 00208 { 00209 QMutexLocker lock(&m_qMutex); 00210 00211 if (m_sFilename.indexOf('-') != -1) 00212 { 00213 m_sArtist = m_sFilename.section('-',0,0).trimmed(); // Get the first part 00214 m_sTitle = m_sFilename.section('-',1,1); // Get the second part 00215 m_sTitle = m_sTitle.section('.',0,-2).trimmed(); // Remove the ending 00216 } 00217 else 00218 { 00219 m_sTitle = m_sFilename.section('.',0,-2).trimmed(); // Remove the ending; 00220 m_sType = m_sFilename.section('.',-1).trimmed(); // Get the ending 00221 } 00222 00223 if (m_sTitle.length() == 0) { 00224 m_sTitle = m_sFilename.section('.',0,-2).trimmed(); 00225 } 00226 00227 // Add no comment 00228 m_sComment = QString(""); 00229 00230 // Find the type 00231 m_sType = m_sFilename.section(".",-1).toLower().trimmed(); 00232 setDirty(true); 00233 } 00234 00235 QString TrackInfoObject::getDurationStr() const 00236 { 00237 QMutexLocker lock(&m_qMutex); 00238 int iDuration = m_iDuration; 00239 lock.unlock(); 00240 00241 return MixxxUtils::secondsToMinutes(iDuration, true); 00242 } 00243 00244 void TrackInfoObject::setLocation(QString location) 00245 { 00246 QMutexLocker lock(&m_qMutex); 00247 QFileInfo fileInfo(location); 00248 // TODO(XXX) Can the file name change without m_sLocation changing?? The 00249 // extra test seems pointless. 00250 QString fileName = fileInfo.fileName(); 00251 bool dirty = m_sLocation != location || fileName != m_sFilename; 00252 populateLocation(fileInfo); 00253 if (dirty) { 00254 m_bLocationChanged = true; 00255 setDirty(true); 00256 } 00257 } 00258 00259 QString TrackInfoObject::getLocation() const 00260 { 00261 QMutexLocker lock(&m_qMutex); 00262 return m_sLocation; 00263 } 00264 00265 QString TrackInfoObject::getDirectory() const 00266 { 00267 QMutexLocker lock(&m_qMutex); 00268 return m_sDirectory; 00269 } 00270 00271 QString TrackInfoObject::getFilename() const 00272 { 00273 QMutexLocker lock(&m_qMutex); 00274 return m_sFilename; 00275 } 00276 00277 QDateTime TrackInfoObject::getCreateDate() const 00278 { 00279 QMutexLocker lock(&m_qMutex); 00280 QDateTime create_date = QDateTime(m_dCreateDate); 00281 return create_date; 00282 } 00283 00284 bool TrackInfoObject::exists() const 00285 { 00286 QMutexLocker lock(&m_qMutex); 00287 return m_bExists; 00288 } 00289 00290 float TrackInfoObject::getReplayGain() const 00291 { 00292 QMutexLocker lock(&m_qMutex); 00293 return m_fReplayGain; 00294 } 00295 00296 void TrackInfoObject::setReplayGain(float f) 00297 { 00298 QMutexLocker lock(&m_qMutex); 00299 bool dirty = m_fReplayGain != f; 00300 m_fReplayGain = f; 00301 //qDebug() << "Reported ReplayGain value: " << m_fReplayGain; 00302 if (dirty) 00303 setDirty(true); 00304 lock.unlock(); 00305 emit(ReplayGainUpdated(f)); 00306 } 00307 00308 float TrackInfoObject::getBpm() const 00309 { 00310 QMutexLocker lock(&m_qMutex); 00311 return m_fBpm; 00312 } 00313 00314 00315 00316 void TrackInfoObject::setBpm(float f) 00317 { 00318 QMutexLocker lock(&m_qMutex); 00319 bool dirty = m_fBpm != f; 00320 m_fBpm = f; 00321 if (dirty) 00322 setDirty(true); 00323 00324 lock.unlock(); 00325 //Tell the GUI to update the bpm label... 00326 //qDebug() << "TrackInfoObject signaling BPM update to" << f; 00327 emit(bpmUpdated(f)); 00328 } 00329 00330 QString TrackInfoObject::getBpmStr() const 00331 { 00332 return QString("%1").arg(getBpm(), 3,'f',1); 00333 } 00334 00335 bool TrackInfoObject::getBpmConfirm() const 00336 { 00337 QMutexLocker lock(&m_qMutex); 00338 return m_bBpmConfirm; 00339 } 00340 00341 void TrackInfoObject::setBpmConfirm(bool confirm) 00342 { 00343 QMutexLocker lock(&m_qMutex); 00344 m_bBpmConfirm = confirm; 00345 } 00346 00347 void TrackInfoObject::setBeats(BeatsPointer pBeats) { 00348 QMutexLocker lock(&m_qMutex); 00349 00350 // This whole method is not so great. The fact that Beats is an ABC is 00351 // limiting with respect to QObject and signals/slots. 00352 00353 QObject* pObject = NULL; 00354 if (m_pBeats) { 00355 pObject = dynamic_cast<QObject*>(m_pBeats.data()); 00356 if (pObject) 00357 pObject->disconnect(this, SIGNAL(updated())); 00358 } 00359 m_pBeats = pBeats; 00360 pObject = dynamic_cast<QObject*>(m_pBeats.data()); 00361 Q_ASSERT(pObject); 00362 if (pObject) { 00363 connect(pObject, SIGNAL(updated()), 00364 this, SLOT(slotBeatsUpdated())); 00365 } 00366 setDirty(true); 00367 lock.unlock(); 00368 emit(beatsUpdated()); 00369 } 00370 00371 BeatsPointer TrackInfoObject::getBeats() const { 00372 QMutexLocker lock(&m_qMutex); 00373 return m_pBeats; 00374 } 00375 00376 void TrackInfoObject::slotBeatsUpdated() { 00377 QMutexLocker lock(&m_qMutex); 00378 setDirty(true); 00379 lock.unlock(); 00380 emit(beatsUpdated()); 00381 } 00382 00383 bool TrackInfoObject::getHeaderParsed() const 00384 { 00385 QMutexLocker lock(&m_qMutex); 00386 return m_bHeaderParsed; 00387 } 00388 00389 void TrackInfoObject::setHeaderParsed(bool parsed) 00390 { 00391 QMutexLocker lock(&m_qMutex); 00392 bool dirty = m_bHeaderParsed != parsed; 00393 m_bHeaderParsed = parsed; 00394 if (dirty) 00395 setDirty(true); 00396 } 00397 00398 QString TrackInfoObject::getInfo() const 00399 { 00400 QMutexLocker lock(&m_qMutex); 00401 QString artist = m_sArtist.trimmed() == "" ? "" : m_sArtist + ", "; 00402 QString sInfo = artist + m_sTitle; 00403 return sInfo; 00404 } 00405 00406 QDateTime TrackInfoObject::getDateAdded() const { 00407 QMutexLocker lock(&m_qMutex); 00408 return m_dateAdded; 00409 } 00410 00411 void TrackInfoObject::setDateAdded(QDateTime dateAdded) { 00412 QMutexLocker lock(&m_qMutex); 00413 m_dateAdded = dateAdded; 00414 } 00415 00416 int TrackInfoObject::getDuration() const 00417 { 00418 QMutexLocker lock(&m_qMutex); 00419 return m_iDuration; 00420 } 00421 00422 void TrackInfoObject::setDuration(int i) 00423 { 00424 QMutexLocker lock(&m_qMutex); 00425 bool dirty = m_iDuration != i; 00426 m_iDuration = i; 00427 if (dirty) 00428 setDirty(true); 00429 } 00430 00431 QString TrackInfoObject::getTitle() const 00432 { 00433 QMutexLocker lock(&m_qMutex); 00434 return m_sTitle; 00435 } 00436 00437 void TrackInfoObject::setTitle(QString s) 00438 { 00439 QMutexLocker lock(&m_qMutex); 00440 s = s.trimmed(); 00441 bool dirty = m_sTitle != s; 00442 m_sTitle = s; 00443 if (dirty) 00444 setDirty(true); 00445 } 00446 00447 QString TrackInfoObject::getArtist() const 00448 { 00449 QMutexLocker lock(&m_qMutex); 00450 return m_sArtist; 00451 } 00452 00453 void TrackInfoObject::setArtist(QString s) 00454 { 00455 QMutexLocker lock(&m_qMutex); 00456 s = s.trimmed(); 00457 bool dirty = m_sArtist != s; 00458 m_sArtist = s; 00459 if (dirty) 00460 setDirty(true); 00461 } 00462 00463 QString TrackInfoObject::getAlbum() const 00464 { 00465 QMutexLocker lock(&m_qMutex); 00466 return m_sAlbum; 00467 } 00468 00469 void TrackInfoObject::setAlbum(QString s) 00470 { 00471 QMutexLocker lock(&m_qMutex); 00472 s = s.trimmed(); 00473 bool dirty = m_sAlbum != s; 00474 m_sAlbum = s; 00475 if (dirty) 00476 setDirty(true); 00477 } 00478 00479 QString TrackInfoObject::getYear() const 00480 { 00481 QMutexLocker lock(&m_qMutex); 00482 return m_sYear; 00483 } 00484 00485 void TrackInfoObject::setYear(QString s) 00486 { 00487 QMutexLocker lock(&m_qMutex); 00488 s = s.trimmed(); 00489 bool dirty = m_sYear != s; 00490 m_sYear = s.trimmed(); 00491 if (dirty) 00492 setDirty(true); 00493 } 00494 00495 QString TrackInfoObject::getGenre() const 00496 { 00497 QMutexLocker lock(&m_qMutex); 00498 return m_sGenre; 00499 } 00500 00501 void TrackInfoObject::setGenre(QString s) 00502 { 00503 QMutexLocker lock(&m_qMutex); 00504 s = s.trimmed(); 00505 bool dirty = m_sGenre != s; 00506 m_sGenre = s; 00507 if (dirty) 00508 setDirty(true); 00509 } 00510 00511 QString TrackInfoObject::getTrackNumber() const 00512 { 00513 QMutexLocker lock(&m_qMutex); 00514 return m_sTrackNumber; 00515 } 00516 00517 void TrackInfoObject::setTrackNumber(QString s) 00518 { 00519 QMutexLocker lock(&m_qMutex); 00520 s = s.trimmed(); 00521 bool dirty = m_sTrackNumber != s; 00522 m_sTrackNumber = s; 00523 if (dirty) 00524 setDirty(true); 00525 } 00526 00527 int TrackInfoObject::getTimesPlayed() const 00528 { 00529 QMutexLocker lock(&m_qMutex); 00530 return m_iTimesPlayed; 00531 } 00532 00533 void TrackInfoObject::setTimesPlayed(int t) 00534 { 00535 QMutexLocker lock(&m_qMutex); 00536 bool dirty = t != m_iTimesPlayed; 00537 m_iTimesPlayed = t; 00538 if (dirty) 00539 setDirty(true); 00540 } 00541 00542 void TrackInfoObject::incTimesPlayed() 00543 { 00544 setPlayed(true); //setPlayed increases play count 00545 } 00546 00547 bool TrackInfoObject::getPlayed() const 00548 { 00549 QMutexLocker lock(&m_qMutex); 00550 bool bPlayed = m_bPlayed; 00551 return bPlayed; 00552 } 00553 00554 void TrackInfoObject::setPlayed(bool bPlayed) 00555 { 00556 QMutexLocker lock(&m_qMutex); 00557 if (bPlayed) { 00558 ++m_iTimesPlayed; 00559 setDirty(true); 00560 } 00561 else if (m_bPlayed && !bPlayed) { 00562 --m_iTimesPlayed; 00563 setDirty(true); 00564 } 00565 m_bPlayed = bPlayed; 00566 } 00567 00568 QString TrackInfoObject::getComment() const 00569 { 00570 QMutexLocker lock(&m_qMutex); 00571 return m_sComment; 00572 } 00573 00574 void TrackInfoObject::setComment(QString s) 00575 { 00576 QMutexLocker lock(&m_qMutex); 00577 bool dirty = s != m_sComment; 00578 m_sComment = s; 00579 if (dirty) 00580 setDirty(true); 00581 } 00582 00583 QString TrackInfoObject::getType() const 00584 { 00585 QMutexLocker lock(&m_qMutex); 00586 return m_sType; 00587 } 00588 00589 void TrackInfoObject::setType(QString s) 00590 { 00591 QMutexLocker lock(&m_qMutex); 00592 bool dirty = s != m_sType; 00593 m_sType = s; 00594 if (dirty) 00595 setDirty(true); 00596 } 00597 00598 void TrackInfoObject::setSampleRate(int iSampleRate) 00599 { 00600 QMutexLocker lock(&m_qMutex); 00601 bool dirty = m_iSampleRate != iSampleRate; 00602 m_iSampleRate = iSampleRate; 00603 if (dirty) 00604 setDirty(true); 00605 } 00606 00607 int TrackInfoObject::getSampleRate() const 00608 { 00609 QMutexLocker lock(&m_qMutex); 00610 return m_iSampleRate; 00611 } 00612 00613 void TrackInfoObject::setChannels(int iChannels) 00614 { 00615 QMutexLocker lock(&m_qMutex); 00616 bool dirty = m_iChannels != iChannels; 00617 m_iChannels = iChannels; 00618 if (dirty) 00619 setDirty(true); 00620 } 00621 00622 int TrackInfoObject::getChannels() const 00623 { 00624 QMutexLocker lock(&m_qMutex); 00625 return m_iChannels; 00626 } 00627 00628 int TrackInfoObject::getLength() const 00629 { 00630 QMutexLocker lock(&m_qMutex); 00631 return m_iLength; 00632 } 00633 00634 int TrackInfoObject::getBitrate() const 00635 { 00636 QMutexLocker lock(&m_qMutex); 00637 return m_iBitrate; 00638 } 00639 00640 QString TrackInfoObject::getBitrateStr() const 00641 { 00642 return QString("%1").arg(getBitrate()); 00643 } 00644 00645 void TrackInfoObject::setBitrate(int i) 00646 { 00647 QMutexLocker lock(&m_qMutex); 00648 bool dirty = m_iBitrate != i; 00649 m_iBitrate = i; 00650 if (dirty) 00651 setDirty(true); 00652 } 00653 00654 void TrackInfoObject::setBeatFirst(float fBeatFirstPos) 00655 { 00656 QMutexLocker lock(&m_qMutex); 00657 bool dirty = m_fBeatFirst != fBeatFirstPos; 00658 m_fBeatFirst = fBeatFirstPos; 00659 if (dirty) 00660 setDirty(true); 00661 } 00662 00663 float TrackInfoObject::getBeatFirst() const 00664 { 00665 QMutexLocker lock(&m_qMutex); 00666 return m_fBeatFirst; 00667 } 00668 00669 int TrackInfoObject::getId() const { 00670 QMutexLocker lock(&m_qMutex); 00671 return m_iId; 00672 } 00673 00674 void TrackInfoObject::setId(int iId) { 00675 QMutexLocker lock(&m_qMutex); 00676 bool dirty = m_iId != iId; 00677 m_iId = iId; 00678 if (dirty) 00679 setDirty(true); 00680 } 00681 00682 QVector<float> * TrackInfoObject::getVisualWaveform() { 00683 QMutexLocker lock(&m_qMutex); 00684 return m_pVisualWave; 00685 } 00686 00687 void TrackInfoObject::setVisualResampleRate(double dVisualResampleRate) { 00688 // Temporary, shared value that should not be saved. The only reason it 00689 // exists on the TIO is a temporary hack, so it does not dirty the TIO. 00690 QMutexLocker lock(&m_qMutex); 00691 m_dVisualResampleRate = dVisualResampleRate; 00692 } 00693 00694 double TrackInfoObject::getVisualResampleRate() { 00695 QMutexLocker lock(&m_qMutex); 00696 return m_dVisualResampleRate; 00697 } 00698 00699 const QByteArray *TrackInfoObject::getWaveSummary() 00700 { 00701 QMutexLocker lock(&m_qMutex); 00702 return &m_waveSummary; 00703 } 00704 00705 void TrackInfoObject::setVisualWaveform(QVector<float> *pWave) { 00706 // The visual waveform is not serialized currently so it does not dirty a 00707 // TIO. 00708 QMutexLocker lock(&m_qMutex); 00709 m_pVisualWave = pWave; 00710 } 00711 00712 void TrackInfoObject::setWaveSummary(const QByteArray* pWave, bool updateUI) 00713 { 00714 QMutexLocker lock(&m_qMutex); 00715 m_waveSummary = *pWave; //_Copy_ the bytes 00716 setDirty(true); 00717 lock.unlock(); 00718 emit(wavesummaryUpdated(this)); 00719 } 00720 00721 void TrackInfoObject::setURL(QString url) 00722 { 00723 QMutexLocker lock(&m_qMutex); 00724 bool dirty = m_sURL != url; 00725 m_sURL = url; 00726 if (dirty) 00727 setDirty(true); 00728 } 00729 00730 QString TrackInfoObject::getURL() 00731 { 00732 QMutexLocker lock(&m_qMutex); 00733 return m_sURL; 00734 } 00735 00736 void TrackInfoObject::setCuePoint(float cue) 00737 { 00738 QMutexLocker lock(&m_qMutex); 00739 bool dirty = m_fCuePoint != cue; 00740 m_fCuePoint = cue; 00741 if (dirty) 00742 setDirty(true); 00743 } 00744 00745 float TrackInfoObject::getCuePoint() 00746 { 00747 QMutexLocker lock(&m_qMutex); 00748 return m_fCuePoint; 00749 } 00750 00751 void TrackInfoObject::slotCueUpdated() { 00752 setDirty(true); 00753 emit(cuesUpdated()); 00754 } 00755 00756 Cue* TrackInfoObject::addCue() { 00757 //qDebug() << "TrackInfoObject::addCue()"; 00758 QMutexLocker lock(&m_qMutex); 00759 Cue* cue = new Cue(m_iId); 00760 connect(cue, SIGNAL(updated()), 00761 this, SLOT(slotCueUpdated())); 00762 m_cuePoints.push_back(cue); 00763 setDirty(true); 00764 lock.unlock(); 00765 emit(cuesUpdated()); 00766 return cue; 00767 } 00768 00769 void TrackInfoObject::removeCue(Cue* cue) { 00770 QMutexLocker lock(&m_qMutex); 00771 disconnect(cue, 0, this, 0); 00772 m_cuePoints.removeOne(cue); 00773 setDirty(true); 00774 lock.unlock(); 00775 emit(cuesUpdated()); 00776 } 00777 00778 const QList<Cue*>& TrackInfoObject::getCuePoints() { 00779 QMutexLocker lock(&m_qMutex); 00780 return m_cuePoints; 00781 } 00782 00783 void TrackInfoObject::setCuePoints(QList<Cue*> cuePoints) { 00784 //qDebug() << "setCuePoints" << cuePoints.length(); 00785 QMutexLocker lock(&m_qMutex); 00786 QListIterator<Cue*> it(m_cuePoints); 00787 while (it.hasNext()) { 00788 Cue* cue = it.next(); 00789 disconnect(cue, 0, this, 0); 00790 } 00791 m_cuePoints = cuePoints; 00792 it = QListIterator<Cue*>(m_cuePoints); 00793 while (it.hasNext()) { 00794 Cue* cue = it.next(); 00795 connect(cue, SIGNAL(updated()), 00796 this, SLOT(slotCueUpdated())); 00797 } 00798 setDirty(true); 00799 lock.unlock(); 00800 emit(cuesUpdated()); 00801 } 00802 00803 const Segmentation<QString>* TrackInfoObject::getChordData() { 00804 QMutexLocker lock(&m_qMutex); 00805 return &m_chordData; 00806 } 00807 00808 void TrackInfoObject::setChordData(Segmentation<QString> cd) { 00809 QMutexLocker lock(&m_qMutex); 00810 m_chordData = cd; 00811 setDirty(true); 00812 } 00813 00814 void TrackInfoObject::setDirty(bool bDirty) { 00815 00816 QMutexLocker lock(&m_qMutex); 00817 bool change = m_bDirty != bDirty; 00818 m_bDirty = bDirty; 00819 lock.unlock(); 00820 // qDebug() << "Track" << m_iId << getInfo() << (change? "changed" : "unchanged") 00821 // << "set" << (bDirty ? "dirty" : "clean"); 00822 if (change) { 00823 if (m_bDirty) 00824 emit(dirty(this)); 00825 else 00826 emit(clean(this)); 00827 } 00828 // Emit a changed signal regardless if this attempted to set us dirty. 00829 if (bDirty) 00830 emit(changed(this)); 00831 00832 //qDebug() << QString("TrackInfoObject %1 %2 set to %3").arg(m_iId).arg(m_sLocation).arg(m_bDirty ? "dirty" : "clean"); 00833 } 00834 00835 bool TrackInfoObject::isDirty() { 00836 QMutexLocker lock(&m_qMutex); 00837 return m_bDirty; 00838 } 00839 00840 bool TrackInfoObject::locationChanged() { 00841 QMutexLocker lock(&m_qMutex); 00842 return m_bLocationChanged; 00843 } 00844 00845 int TrackInfoObject::getRating() const{ 00846 QMutexLocker lock(&m_qMutex); 00847 return m_Rating; 00848 } 00849 00850 void TrackInfoObject::setRating (int rating){ 00851 QMutexLocker lock(&m_qMutex); 00852 bool dirty = rating != m_Rating; 00853 m_Rating = rating; 00854 if (dirty) 00855 setDirty(true); 00856 } 00857 00858 QString TrackInfoObject::getKey() const{ 00859 QMutexLocker lock(&m_qMutex); 00860 return m_key; 00861 } 00862 00863 void TrackInfoObject::setKey(QString key){ 00864 QMutexLocker lock(&m_qMutex); 00865 bool dirty = key != m_key; 00866 m_key = key; 00867 if (dirty) 00868 setDirty(true); 00869 } 00870