#include "track/track.h"
#include <QDirIterator>
#include <QMutexLocker>
#include <atomic>
#include "engine/engine.h"
#include "track/beatfactory.h"
#include "track/trackref.h"
#include "util/assert.h"
#include "util/color/color.h"
#include "util/logger.h"
namespace {
const mixxx::Logger kLogger("Track");
constexpr bool kLogStats = false;
// Count the number of currently existing instances for detecting
// memory leaks.
std::atomic<int> s_numberOfInstances;
SecurityTokenPointer openSecurityToken(
const TrackFile& trackFile,
SecurityTokenPointer pSecurityToken = SecurityTokenPointer()) {
if (pSecurityToken.isNull()) {
return Sandbox::openSecurityToken(trackFile.asFileInfo(), true);
} else {
return pSecurityToken;
}
}
template<typename T>
inline
bool compareAndSet(T* pField, const T& value) {
if (*pField != value) {
*pField = value;
return true;
} else {
return false;
}
}
inline
mixxx::Bpm getActualBpm(
mixxx::Bpm bpm,
BeatsPointer pBeats = BeatsPointer()) {
// Only use the imported BPM if the beat grid is not valid!
// Reason: The BPM value in the metadata might be normalized
// or rounded, e.g. ID3v2 only supports integer values.
if (pBeats) {
return mixxx::Bpm(pBeats->getBpm());
} else {
return bpm;
}
}
} // anonymous namespace
Track::Track(
TrackFile fileInfo,
SecurityTokenPointer pSecurityToken,
TrackId trackId)
: m_qMutex(QMutex::Recursive),
m_fileInfo(std::move(fileInfo)),
m_pSecurityToken(openSecurityToken(m_fileInfo, std::move(pSecurityToken))),
m_record(trackId),
m_bDirty(false),
m_bMarkedForMetadataExport(false) {
if (kLogStats && kLogger.debugEnabled()) {
long numberOfInstancesBefore = s_numberOfInstances.fetch_add(1);
kLogger.debug()
<< "Creating instance:"
<< this
<< numberOfInstancesBefore
<< "->"
<< numberOfInstancesBefore + 1;
}
}
Track::~Track() {
if (kLogStats && kLogger.debugEnabled()) {
long numberOfInstancesBefore = s_numberOfInstances.fetch_sub(1);
kLogger.debug()
<< "Destroying instance:"
<< this
<< numberOfInstancesBefore
<< "->"
<< numberOfInstancesBefore - 1;
}
}
//static
TrackPointer Track::newTemporary(
TrackFile fileInfo,
SecurityTokenPointer pSecurityToken) {
return std::make_shared<Track>(
std::move(fileInfo),
std::move(pSecurityToken));
}
//static
TrackPointer Track::newDummy(
TrackFile fileInfo,
TrackId trackId) {
return std::make_shared<Track>(
std::move(fileInfo),
SecurityTokenPointer