Skip to content

Commit

Permalink
track/serato: Import saved loops from serato's tags
Browse files Browse the repository at this point in the history
  • Loading branch information
Holzhaus committed Apr 23, 2020
1 parent 6f4fc0b commit 41f3717
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 9 deletions.
17 changes: 16 additions & 1 deletion src/track/serato/markers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ QList<CueInfo> SeratoMarkers::getCues(double timingOffsetMillis) const {

QList<CueInfo> cueInfos;
int cueIndex = 0;
int loopIndex = 0;
for (const auto& pEntry : m_entries) {
DEBUG_ASSERT(pEntry);
switch (pEntry->typeId()) {
Expand All @@ -306,7 +307,21 @@ QList<CueInfo> SeratoMarkers::getCues(double timingOffsetMillis) const {
cueIndex++;
break;
}
// TODO: Add support for Loops
case SeratoMarkersEntry::TypeId::Loop: {
if (pEntry->hasStartPosition()) {
CueInfo loopInfo = CueInfo(
CueType::Loop,
pEntry->getStartPosition() + timingOffsetMillis,
pEntry->getEndPosition() + timingOffsetMillis,
loopIndex,
"",
std::nullopt);
cueInfos.append(loopInfo);
// TODO: Add support for the "locked" attribute
}
loopIndex++;
break;
}
default:
break;
}
Expand Down
18 changes: 16 additions & 2 deletions src/track/serato/markers2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ QByteArray SeratoMarkers2::dump() const {

QList<CueInfo> SeratoMarkers2::getCues(double timingOffsetMillis) const {
qDebug() << "Reading cues from 'Serato Markers2' tag data...";

QList<CueInfo> cueInfos;
for (auto& pEntry : m_entries) {
DEBUG_ASSERT(pEntry);
Expand All @@ -454,10 +455,23 @@ QList<CueInfo> SeratoMarkers2::getCues(double timingOffsetMillis) const {
pCueEntry->getLabel(),
pCueEntry->getColor());
cueInfos.append(cueInfo);

break;
}
// TODO: Add support for LOOP/FLIP
case SeratoMarkers2Entry::TypeId::Loop: {
const SeratoMarkers2LoopEntry* pLoopEntry =
static_cast<SeratoMarkers2LoopEntry*>(pEntry.get());
CueInfo loopInfo = CueInfo(
CueType::Loop,
pLoopEntry->getStartPosition() + timingOffsetMillis,
pLoopEntry->getEndPosition() + timingOffsetMillis,
pLoopEntry->getIndex(),
pLoopEntry->getLabel(),
std::nullopt); // Serato's Loops don't have a color
// TODO: Add support for "locked" loops
cueInfos.append(loopInfo);
break;
}
// TODO: Add support for FLIP
default:
break;
}
Expand Down
45 changes: 39 additions & 6 deletions src/track/serato/tags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const QString kDecoderName(QStringLiteral("FFMPEG"));
const QString kDecoderName(QStringLiteral("Unknown"));
#endif

const int kLoopIndexOffset = 8;

mixxx::RgbColor getColorFromOtherPalette(
const ColorPalette& source,
const ColorPalette& dest,
Expand Down Expand Up @@ -156,6 +158,11 @@ QList<CueInfo> SeratoTags::getCues(const QString& filePath) const {
// from "Serato Markers_". This is what Serato does too (i.e. if
// "Serato Markers_" and "Serato Markers2" contradict each other,
// Serato will use the values from "Serato Markers_").
//
// In Serato, loops and hotcues are kept separate (i. e. you can
// have a loop and a hotcue with the same number. In Mixxx, loops
// and hotcues share indices. Hence, we import them with and offset
// of 8 (the maximum number of hotcues in Serato).

double timingOffsetMillis = SeratoTags::findTimingOffsetMillis(filePath);

Expand All @@ -171,9 +178,22 @@ QList<CueInfo> SeratoTags::getCues(const QString& filePath) const {
qWarning() << "SeratoTags::getCues: Cue with number < 0 found!";
}

if (cueInfo.getType() != CueType::HotCue) {
qWarning() << "SeratoTags::getCues: Ignoring cue with non-hotcue type!";
continue;
switch (cueInfo.getType()) {
case CueType::HotCue: {
if (index >= kLoopIndexOffset) {
qWarning()
<< "SeratoTags::getCues: Non-loop Cue with number >="
<< kLoopIndexOffset << "found!";
continue;
}
break;
}
case CueType::Loop: {
index += kLoopIndexOffset;
break;
}
default:
break;
}

CueInfo newCueInfo(cueInfo);
Expand All @@ -200,9 +220,22 @@ QList<CueInfo> SeratoTags::getCues(const QString& filePath) const {
qWarning() << "SeratoTags::getCues: Cue with number < 0 found!";
}

if (cueInfo.getType() != CueType::HotCue) {
qWarning() << "SeratoTags::getCues: Ignoring cue with non-hotcue type!";
continue;
switch (cueInfo.getType()) {
case CueType::HotCue: {
if (index >= kLoopIndexOffset) {
qWarning()
<< "SeratoTags::getCues: Non-loop Cue with number >="
<< kLoopIndexOffset << "found!";
continue;
}
break;
}
case CueType::Loop: {
index += kLoopIndexOffset;
break;
}
default:
break;
}

// Take a pre-existing CueInfo object that was read from
Expand Down

0 comments on commit 41f3717

Please sign in to comment.