summaryrefslogtreecommitdiffstats
path: root/src/track
diff options
context:
space:
mode:
authorJan Holthuis <jan.holthuis@ruhr-uni-bochum.de>2020-03-02 10:22:57 +0100
committerJan Holthuis <jan.holthuis@ruhr-uni-bochum.de>2020-03-02 10:22:57 +0100
commitfa6dba8f86420a6eb9979b51f8c10629b4b72466 (patch)
tree0bec26b36e5f9624f4c4dee5b6e5b1ad165261b1 /src/track
parent8d3672390c77b1199171517422149f623ab00d6a (diff)
parent18a134faba514f60a273a9b0aa2f3c9a6a09f214 (diff)
Merge branch 'master' of github.com:mixxxdj/mixxx into hotcue-rgb-colors
Diffstat (limited to 'src/track')
-rw-r--r--src/track/cue.cpp43
-rw-r--r--src/track/cue.h29
-rw-r--r--src/track/cueinfo.cpp86
-rw-r--r--src/track/cueinfo.h61
-rw-r--r--src/track/track.cpp43
-rw-r--r--src/track/track.h5
6 files changed, 230 insertions, 37 deletions
diff --git a/src/track/cue.cpp b/src/track/cue.cpp
index 57406665e8..f39f84ceb6 100644
--- a/src/track/cue.cpp
+++ b/src/track/cue.cpp
@@ -1,10 +1,12 @@
// cue.cpp
// Created 10/26/2009 by RJ Ryan (rryan@mit.edu)
+#include "track/cue.h"
+
#include <QMutexLocker>
#include <QtDebug>
-#include "track/cue.h"
+#include "engine/engine.h"
#include "util/assert.h"
#include "util/color/color.h"
@@ -24,7 +26,7 @@ Cue::Cue(TrackId trackId)
: m_bDirty(false),
m_iId(-1),
m_trackId(trackId),
- m_type(Cue::Type::Invalid),
+ m_type(mixxx::CueType::Invalid),
m_sampleStartPosition(Cue::kNoPosition),
m_sampleEndPosition(Cue::kNoPosition),
m_iHotCue(-1),
@@ -35,7 +37,7 @@ Cue::Cue(TrackId trackId)
Cue::Cue(int id,
TrackId trackId,
- Cue::Type type,
+ mixxx::CueType type,
double position,
double length,
int hotCue,
@@ -60,6 +62,37 @@ Cue::Cue(int id,
m_sampleEndPosition = Cue::kNoPosition;
}
}
+
+Cue::Cue(TrackId trackId, mixxx::AudioSignal::SampleRate sampleRate, const mixxx::CueInfo& cueInfo)
+ : m_bDirty(false),
+ m_iId(-1),
+ m_trackId(trackId),
+ m_type(cueInfo.getType()),
+ m_sampleStartPosition(Cue::kNoPosition),
+ m_sampleEndPosition(Cue::kNoPosition),
+ m_iHotCue(Cue::kNoHotCue),
+ m_label(cueInfo.getLabel()),
+ m_color(cueInfo.getColor().value_or(kDefaultCueColor)) {
+ DEBUG_ASSERT(!m_label.isNull());
+ DEBUG_ASSERT(sampleRate.valid());
+
+ const double sampleRateKhz = sampleRate / 1000.0;
+ const double millisecsToSamplesFactor = sampleRateKhz * mixxx::kEngineChannelCount;
+ DEBUG_ASSERT(millisecsToSamplesFactor > 0);
+
+ if (cueInfo.getStartPositionMillis()) {
+ m_sampleStartPosition = (*cueInfo.getStartPositionMillis()) * millisecsToSamplesFactor;
+ }
+
+ if (cueInfo.getEndPositionMillis()) {
+ m_sampleEndPosition = (*cueInfo.getEndPositionMillis()) * millisecsToSamplesFactor;
+ }
+
+ if (cueInfo.getHotCueNumber()) {
+ m_iHotCue = *cueInfo.getHotCueNumber();
+ }
+}
+
int Cue::getId() const {
QMutexLocker lock(&m_mutex);
return m_iId;
@@ -86,12 +119,12 @@ void Cue::setTrackId(TrackId trackId) {
emit updated();
}
-Cue::Type Cue::getType() const {
+mixxx::CueType Cue::getType() const {
QMutexLocker lock(&m_mutex);
return m_type;
}
-void Cue::setType(Cue::Type type) {
+void Cue::setType(mixxx::CueType type) {
QMutexLocker lock(&m_mutex);
m_type = type;
m_bDirty = true;
diff --git a/src/track/cue.h b/src/track/cue.h
index 34631127fa..71e1387e03 100644
--- a/src/track/cue.h
+++ b/src/track/cue.h
@@ -5,7 +5,9 @@
#include <QMutex>
#include <QObject>
+#include "track/cueinfo.h"
#include "track/trackid.h"
+#include "util/audiosignal.h"
#include "util/color/rgbcolor.h"
#include "util/memory.h"
@@ -17,21 +19,8 @@ class Cue : public QObject {
Q_OBJECT
public:
- enum class Type {
- Invalid = 0,
- HotCue = 1,
- MainCue = 2,
- Beat = 3, // unused (what is this for?)
- Loop = 4,
- Jump = 5,
- Intro = 6,
- Outro = 7,
- AudibleSound = 8, // range that covers beginning and end of audible sound;
- // not shown to user
- };
-
static constexpr double kNoPosition = -1.0;
- static const int kNoHotCue = -1;
+ static constexpr int kNoHotCue = -1;
~Cue() override = default;
@@ -39,8 +28,8 @@ class Cue : public QObject {
int getId() const;
TrackId getTrackId() const;
- Cue::Type getType() const;
- void setType(Cue::Type type);
+ mixxx::CueType getType() const;
+ void setType(mixxx::CueType type);
double getPosition() const;
void setStartPosition(double samplePosition);
@@ -64,9 +53,13 @@ class Cue : public QObject {
private:
explicit Cue(TrackId trackId);
+ explicit Cue(
+ TrackId trackId,
+ mixxx::AudioSignal::SampleRate sampleRate,
+ const mixxx::CueInfo& cueInfo);
Cue(int id,
TrackId trackId,
- Cue::Type type,
+ mixxx::CueType type,
double position,
double length,
int hotCue,
@@ -81,7 +74,7 @@ class Cue : public QObject {
bool m_bDirty;
int m_iId;
TrackId m_trackId;
- Cue::Type m_type;
+ mixxx::CueType m_type;
double m_sampleStartPosition;
double m_sampleEndPosition;
int m_iHotCue;
diff --git a/src/track/cueinfo.cpp b/src/track/cueinfo.cpp
new file mode 100644
index 0000000000..66e092a2b6
--- /dev/null
+++ b/src/track/cueinfo.cpp
@@ -0,0 +1,86 @@
+#include "track/cueinfo.h"
+
+#include "util/assert.h"
+
+namespace {
+const QString kDefaultLabel = QStringLiteral(""); // empty string, not null
+} // anonymous namespace
+
+namespace mixxx {
+
+CueInfo::CueInfo()
+ : m_type(CueType::Invalid),
+ m_startPositionMillis(std::nullopt),
+ m_endPositionMillis(std::nullopt),
+ m_hotCueNumber(std::nullopt),
+ m_label(kDefaultLabel),
+ m_color(std::nullopt) {
+ DEBUG_ASSERT(!m_label.isNull());
+}
+
+CueInfo::CueInfo(
+ CueType type,
+ std::optional<double> startPositionMillis,
+ std::optional<double> endPositionMillis,
+ std::optional<int> hotCueNumber,
+ QString label,
+ mixxx::RgbColor::optional_t color)
+ : m_type(type),
+ m_startPositionMillis(startPositionMillis),
+ m_endPositionMillis(endPositionMillis),
+ m_hotCueNumber(hotCueNumber),
+ m_label(label),
+ m_color(color) {
+ DEBUG_ASSERT(!m_label.isNull());
+}
+
+CueType CueInfo::getType() const {
+ return m_type;
+}
+
+void CueInfo::setType(CueType type) {
+ m_type = type;
+}
+
+void CueInfo::setStartPositionMillis(std::optional<double> positionMillis) {
+ m_startPositionMillis = positionMillis;
+}
+
+std::optional<double> CueInfo::getStartPositionMillis() const {
+ return m_startPositionMillis;
+}
+
+void CueInfo::setEndPositionMillis(std::optional<double> positionMillis) {
+ m_endPositionMillis = positionMillis;
+}
+
+std::optional<double> CueInfo::getEndPositionMillis() const {
+ return m_endPositionMillis;
+}
+
+std::optional<int> CueInfo::getHotCueNumber() const {
+ return m_hotCueNumber;
+}
+
+void CueInfo::setHotCueNumber(std::optional<int> hotCueNumber) {
+ m_hotCueNumber = hotCueNumber;
+}
+
+QString CueInfo::getLabel() const {
+ return m_label;
+}
+
+void CueInfo::setLabel(QString label) {
+ DEBUG_ASSERT(!label.isNull());
+ m_label = label;
+}
+
+RgbColor::optional_t CueInfo::getColor() const {
+ return m_color;
+}
+
+void CueInfo::setColor(RgbColor::optional_t color) {
+ m_color = color;
+}
+
+} // namespace mixxx
diff --git a/src/track/cueinfo.h b/src/track/cueinfo.h
new file mode 100644
index 0000000000..409acd8fd2
--- /dev/null
+++ b/src/track/cueinfo.h
@@ -0,0 +1,61 @@
+#pragma once
+// cueinfo.h
+// Created 2020-02-28 by Jan Holthuis
+
+#include "util/color/rgbcolor.h"
+#include "util/optional.h"
+
+namespace mixxx {
+
+enum class CueType {
+ Invalid = 0,
+ HotCue = 1,
+ MainCue = 2,
+ Beat = 3, // unused (what is this for?)
+ Loop = 4,
+ Jump = 5,
+ Intro = 6,
+ Outro = 7,
+ AudibleSound = 8, // range that covers beginning and end of audible
+ // sound; not shown to user
+};
+
+// DTO for Cue information without dependencies on the actual Track object
+class CueInfo {
+ public:
+ CueInfo();
+ CueInfo(CueType type,
+ std::optional<double> startPositionMillis,
+ std::optional<double> endPositionMillis,
+ std::optional<int> hotCueNumber,
+ QString label,
+ RgbColor::optional_t color);
+
+ CueType getType() const;
+ void setType(CueType type);
+
+ void setStartPositionMillis(std::optional<double> positionMillis);
+ std::optional<double> getStartPositionMillis() const;
+
+ void setEndPositionMillis(std::optional<double> positionMillis);
+ std::optional<double> getEndPositionMillis() const;
+
+ std::optional<int> getHotCueNumber() const;
+ void setHotCueNumber(std::optional<int> hotCueNumber);
+
+ QString getLabel() const;
+ void setLabel(QString label);
+
+ mixxx::RgbColor::optional_t getColor() const;
+ void setColor(mixxx::RgbColor::optional_t color);
+
+ private:
+ CueType m_type;
+ std::optional<double> m_startPositionMillis;
+ std::optional<double> m_endPositionMillis;
+ std::optional<int> m_hotCueNumber;
+ QString m_label;
+ RgbColor::optional_t m_color;
+};
+
+} // namespace mixxx
diff --git a/src/track/track.cpp b/src/track/track.cpp
index 79b7540d6e..ef9fc9d593 100644
--- a/src/track/track.cpp
+++ b/src/track/track.cpp
@@ -1,16 +1,16 @@
+#include "track/track.h"
+
#include <QDirIterator>
#include <QMutexLocker>
-
#include <atomic>
-#include "track/track.h"
-#include "track/trackref.h"
+#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");
@@ -671,12 +671,12 @@ void Track::setCuePoint(CuePosition cue) {
}
// Store the cue point in a load cue
- CuePointer pLoadCue = findCueByType(Cue::Type::MainCue);
+ CuePointer pLoadCue = findCueByType(mixxx::CueType::MainCue);
double position = cue.getPosition();
if (position != -1.0) {
if (!pLoadCue) {
pLoadCue = CuePointer(new Cue(m_record.getId()));
- pLoadCue->setType(Cue::Type::MainCue);
+ pLoadCue->setType(mixxx::CueType::MainCue);
connect(pLoadCue.get(),
&Cue::updated,
this,
@@ -713,10 +713,12 @@ CuePointer Track::createAndAddCue() {
return pCue;
}
-CuePointer Track::findCueByType(Cue::Type type) const {
+CuePointer Track::findCueByType(mixxx::CueType type) const {
// This method cannot be used for hotcues because there can be
// multiple hotcues and this function returns only a single CuePointer.
- DEBUG_ASSERT(type != Cue::Type::HotCue);
+ VERIFY_OR_DEBUG_ASSERT(type != mixxx::CueType::HotCue) {
+ return CuePointer();
+ }
QMutexLocker lock(&m_qMutex);
for (const CuePointer& pCue: m_cuePoints) {
if (pCue->getType() == type) {
@@ -734,14 +736,14 @@ void Track::removeCue(const CuePointer& pCue) {
QMutexLocker lock(&m_qMutex);
disconnect(pCue.get(), 0, this, 0);
m_cuePoints.removeOne(pCue);
- if (pCue->getType() == Cue::Type::MainCue) {
+ if (pCue->getType() == mixxx::CueType::MainCue) {
m_record.setCuePoint(CuePosition());
}
markDirtyAndUnlock(&lock);
emit cuesUpdated();
}
-void Track::removeCuesOfType(Cue::Type type) {
+void Track::removeCuesOfType(mixxx::CueType type) {
QMutexLocker lock(&m_qMutex);
bool dirty = false;
QMutableListIterator<CuePointer> it(m_cuePoints);
@@ -780,7 +782,7 @@ void Track::setCuePoints(const QList<CuePointer>& cuePoints) {
for (const auto& pCue: m_cuePoints) {
connect(pCue.get(), &Cue::updated, this, &Track::slotCueUpdated);
// update main cue point
- if (pCue->getType() == Cue::Type::MainCue) {
+ if (pCue->getType() == mixxx::CueType::MainCue) {
m_record.setCuePoint(CuePosition(pCue->getPosition()));
}
}
@@ -788,6 +790,23 @@ void Track::setCuePoints(const QList<CuePointer>& cuePoints) {
emit cuesUpdated();
}
+void Track::importCuePoints(const QList<mixxx::CueInfo>& cueInfos) {
+ TrackId trackId;
+ mixxx::AudioSignal::SampleRate sampleRate;
+ {
+ QMutexLocker lock(&m_qMutex);
+ trackId = m_record.getId();
+ sampleRate = m_record.getMetadata().getSampleRate();
+ } // implicitly unlocked when leaving scope
+
+ QList<CuePointer> cuePoints;
+ for (const mixxx::CueInfo& cueInfo : cueInfos) {
+ CuePointer pCue(new Cue(trackId, sampleRate, cueInfo));
+ cuePoints.append(pCue);
+ }
+ setCuePoints(cuePoints);
+}
+
void Track::markDirty() {
QMutexLocker lock(&m_qMutex);
setDirtyAndUnlock(&lock, true);
diff --git a/src/track/track.h b/src/track/track.h
index 487a7fc0b3..266da4d00d 100644
--- a/src/track/track.h
+++ b/src/track/track.h
@@ -251,11 +251,12 @@ class Track : public QObject {
// Calls for managing the track's cue points
CuePointer createAndAddCue();
- CuePointer findCueByType(Cue::Type type) const; // NOTE: Cannot be used for hotcues.
+ CuePointer findCueByType(mixxx::CueType type) const; // NOTE: Cannot be used for hotcues.
void removeCue(const CuePointer& pCue);
- void removeCuesOfType(Cue::Type);
+ void removeCuesOfType(mixxx::CueType);
QList<CuePointer> getCuePoints() const;
void setCuePoints(const QList<CuePointer>& cuePoints);
+ void importCuePoints(const QList<mixxx::CueInfo>& cueInfos);
bool isDirty();