diff options
author | Jan Holthuis <jan.holthuis@ruhr-uni-bochum.de> | 2020-03-02 10:22:57 +0100 |
---|---|---|
committer | Jan Holthuis <jan.holthuis@ruhr-uni-bochum.de> | 2020-03-02 10:22:57 +0100 |
commit | fa6dba8f86420a6eb9979b51f8c10629b4b72466 (patch) | |
tree | 0bec26b36e5f9624f4c4dee5b6e5b1ad165261b1 /src/track | |
parent | 8d3672390c77b1199171517422149f623ab00d6a (diff) | |
parent | 18a134faba514f60a273a9b0aa2f3c9a6a09f214 (diff) |
Merge branch 'master' of github.com:mixxxdj/mixxx into hotcue-rgb-colors
Diffstat (limited to 'src/track')
-rw-r--r-- | src/track/cue.cpp | 43 | ||||
-rw-r--r-- | src/track/cue.h | 29 | ||||
-rw-r--r-- | src/track/cueinfo.cpp | 86 | ||||
-rw-r--r-- | src/track/cueinfo.h | 61 | ||||
-rw-r--r-- | src/track/track.cpp | 43 | ||||
-rw-r--r-- | src/track/track.h | 5 |
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(); |