Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1371,6 +1371,10 @@ add_library(
src/library/autodj/autodjprocessor.cpp
src/library/autodj/dlgautodj.cpp
src/library/autodj/dlgautodj.ui
src/library/autodj/track/deckattributes.cpp
src/library/autodj/track/fadeabletrackordeckattributes.cpp
src/library/autodj/track/trackattributes.cpp
src/library/autodj/track/trackordeckattributes.cpp
src/library/banshee/bansheedbconnection.cpp
src/library/banshee/bansheefeature.cpp
src/library/banshee/bansheeplaylistmodel.cpp
Expand Down
8 changes: 8 additions & 0 deletions src/library/autodj/autodjconstants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

namespace mixxx {
namespace autodj {
static constexpr double kKeepPosition = -1.0;
static constexpr double kSkipToNextTrack = -2.0;
} // namespace autodj
} // namespace mixxx
22 changes: 11 additions & 11 deletions src/library/autodj/autodjfeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@
namespace {
constexpr int kMaxRetrieveAttempts = 3;

int findOrCrateAutoDjPlaylistId(PlaylistDAO& playlistDAO) {
int playlistId = playlistDAO.getPlaylistIdFromName(AUTODJ_TABLE);
// If the AutoDJ playlist does not exist yet then create it.
if (playlistId < 0) {
playlistId = playlistDAO.createPlaylist(
AUTODJ_TABLE, PlaylistDAO::PLHT_AUTO_DJ);
VERIFY_OR_DEBUG_ASSERT(playlistId >= 0) {
qWarning() << "Failed to create Auto DJ playlist!";
}
int findOrCreateAutoDjPlaylistId(PlaylistDAO& playlistDAO) {
int playlistId = playlistDAO.getPlaylistIdFromName(AUTODJ_TABLE);
// If the AutoDJ playlist does not exist yet then create it.
if (playlistId < 0) {
playlistId = playlistDAO.createPlaylist(
AUTODJ_TABLE, PlaylistDAO::PLHT_AUTO_DJ);
VERIFY_OR_DEBUG_ASSERT(playlistId >= 0) {
qWarning() << "Failed to create Auto DJ playlist!";
}
return playlistId;
}
return playlistId;
}
} // anonymous namespace

AutoDJFeature::AutoDJFeature(Library* pLibrary,
Expand All @@ -45,7 +45,7 @@ AutoDJFeature::AutoDJFeature(Library* pLibrary,
: LibraryFeature(pLibrary, pConfig, QStringLiteral("autodj")),
m_pTrackCollection(pLibrary->trackCollectionManager()->internalCollection()),
m_playlistDao(m_pTrackCollection->getPlaylistDAO()),
m_iAutoDJPlaylistId(findOrCrateAutoDjPlaylistId(m_playlistDao)),
m_iAutoDJPlaylistId(findOrCreateAutoDjPlaylistId(m_playlistDao)),
m_pAutoDJProcessor(nullptr),
m_pSidebarModel(make_parented<TreeItemModel>(this)),
m_pAutoDJView(nullptr),
Expand Down
515 changes: 232 additions & 283 deletions src/library/autodj/autodjprocessor.cpp

Large diffs are not rendered by default.

153 changes: 20 additions & 133 deletions src/library/autodj/autodjprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "control/controlpushbutton.h"
#include "control/pollingcontrolproxy.h"
#include "engine/channels/enginechannel.h"
#include "library/autodj/track/deckattributes.h"
#include "library/autodj/track/trackattributes.h"
#include "library/playlisttablemodel.h"
#include "preferences/usersettings.h"
#include "track/track_decl.h"
Expand All @@ -18,130 +20,9 @@

class TrackCollectionManager;
class PlayerManagerInterface;
class BaseTrackPlayer;
class PlaylistTableModel;
typedef QList<QModelIndex> QModelIndexList;

class DeckAttributes : public QObject {
Q_OBJECT
public:
DeckAttributes(int index,
BaseTrackPlayer* pPlayer);
virtual ~DeckAttributes();

bool isLeft() const {
return m_orientation.get() == static_cast<double>(EngineChannel::LEFT);
}

bool isRight() const {
return m_orientation.get() == static_cast<double>(EngineChannel::RIGHT);
}

bool isPlaying() const {
return m_play.toBool();
}

void stop() {
m_play.set(0.0);
}

void play() {
m_play.set(1.0);
}

double playPosition() const {
return m_playPos.get();
}

void setPlayPosition(double playpos) {
m_playPos.set(playpos);
}

bool isRepeat() const {
return m_repeat.toBool();
}

void setRepeat(bool enabled) {
m_repeat.set(enabled ? 1.0 : 0.0);
}

mixxx::audio::FramePos introStartPosition() const {
return mixxx::audio::FramePos::fromEngineSamplePosMaybeInvalid(m_introStartPos.get());
}

mixxx::audio::FramePos introEndPosition() const {
return mixxx::audio::FramePos::fromEngineSamplePosMaybeInvalid(m_introEndPos.get());
}

mixxx::audio::FramePos outroStartPosition() const {
return mixxx::audio::FramePos::fromEngineSamplePosMaybeInvalid(m_outroStartPos.get());
}

mixxx::audio::FramePos outroEndPosition() const {
return mixxx::audio::FramePos::fromEngineSamplePosMaybeInvalid(m_outroEndPos.get());
}

mixxx::audio::SampleRate sampleRate() const {
return mixxx::audio::SampleRate::fromDouble(m_sampleRate.get());
}

mixxx::audio::FramePos trackEndPosition() const {
return mixxx::audio::FramePos::fromEngineSamplePosMaybeInvalid(m_trackSamples.get());
}

double rateRatio() const {
return m_rateRatio.get();
}

TrackPointer getLoadedTrack() const;

signals:
void playChanged(DeckAttributes* pDeck, bool playing);
void playPositionChanged(DeckAttributes* pDeck, double playPosition);
void introStartPositionChanged(DeckAttributes* pDeck, double introStartPosition);
void introEndPositionChanged(DeckAttributes* pDeck, double introEndPosition);
void outroStartPositionChanged(DeckAttributes* pDeck, double outtroStartPosition);
void outroEndPositionChanged(DeckAttributes* pDeck, double outroEndPosition);
void trackLoaded(DeckAttributes* pDeck, TrackPointer pTrack);
void loadingTrack(DeckAttributes* pDeck, TrackPointer pNewTrack, TrackPointer pOldTrack);
void playerEmpty(DeckAttributes* pDeck);
void rateChanged(DeckAttributes* pDeck);

private slots:
void slotPlayPosChanged(double v);
void slotPlayChanged(double v);
void slotIntroStartPositionChanged(double v);
void slotIntroEndPositionChanged(double v);
void slotOutroStartPositionChanged(double v);
void slotOutroEndPositionChanged(double v);
void slotTrackLoaded(TrackPointer pTrack);
void slotLoadingTrack(TrackPointer pNewTrack, TrackPointer pOldTrack);
void slotPlayerEmpty();
void slotRateChanged(double v);

public:
int index;
QString group;
double startPos; // Set in toDeck nature
double fadeBeginPos; // set in fromDeck nature
double fadeEndPos; // set in fromDeck nature
bool isFromDeck;
bool loading; // The data is inconsistent during loading a deck

private:
ControlProxy m_orientation;
ControlProxy m_playPos;
ControlProxy m_play;
ControlProxy m_repeat;
ControlProxy m_introStartPos;
ControlProxy m_introEndPos;
ControlProxy m_outroStartPos;
ControlProxy m_outroEndPos;
ControlProxy m_trackSamples;
ControlProxy m_sampleRate;
ControlProxy m_rateRatio;
BaseTrackPlayer* m_pPlayer;
};

class AutoDJProcessor : public QObject {
Q_OBJECT
public:
Expand Down Expand Up @@ -263,23 +144,29 @@ class AutoDJProcessor : public QObject {

// Following functions return seconds computed from samples or -1 if
// track in deck has invalid sample rate (<= 0)
double getIntroStartSecond(DeckAttributes* pDeck);
double getIntroEndSecond(DeckAttributes* pDeck);
double getOutroStartSecond(DeckAttributes* pDeck);
double getOutroEndSecond(DeckAttributes* pDeck);
double getFirstSoundSecond(DeckAttributes* pDeck);
double getLastSoundSecond(DeckAttributes* pDeck);
double getEndSecond(DeckAttributes* pDeck);
double framePositionToSeconds(mixxx::audio::FramePos position, DeckAttributes* pDeck);
double getIntroStartSecond(const TrackOrDeckAttributes& track);
double getIntroEndSecond(const TrackOrDeckAttributes& track);
double getOutroStartSecond(const TrackOrDeckAttributes& track);
double getOutroEndSecond(const TrackOrDeckAttributes& track);
double getFirstSoundSecond(const TrackOrDeckAttributes& track);
double getLastSoundSecond(const TrackOrDeckAttributes& track);
double getEndSecond(const TrackOrDeckAttributes& track);
double framePositionToSeconds(mixxx::audio::FramePos position,
const TrackOrDeckAttributes& track);

TrackPointer getNextTrackFromQueue();
bool loadNextTrackFromQueue(const DeckAttributes& pDeck, bool play = false);
void calculateTransition(DeckAttributes* pFromDeck,
void calculateTransition(
DeckAttributes* pFromDeck,
DeckAttributes* pToDeck,
bool seekToStartPoint);
void calculateTransitionImpl(
FadeableTrackOrDeckAttributes* pFromDeck,
FadeableTrackOrDeckAttributes* pToDeck,
bool seekToStartPoint);
void useFixedFadeTime(
DeckAttributes* pFromDeck,
DeckAttributes* pToDeck,
FadeableTrackOrDeckAttributes* fromTrack,
FadeableTrackOrDeckAttributes* toTrack,
double fromDeckSecond,
double fadeEndSecond,
double toDeckStartSecond);
Expand Down
81 changes: 81 additions & 0 deletions src/library/autodj/track/deckattributes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include "library/autodj/track/deckattributes.h"

#include "mixer/basetrackplayer.h"
#include "moc_deckattributes.cpp"

DeckAttributes::DeckAttributes(int index,
BaseTrackPlayer* pPlayer)
: index(index),
group(pPlayer->getGroup()),
loading(false),
m_orientation(group, "orientation"),
m_playPos(group, "playposition"),
m_play(group, "play"),
m_repeat(group, "repeat"),
m_introStartPos(group, "intro_start_position"),
m_introEndPos(group, "intro_end_position"),
m_outroStartPos(group, "outro_start_position"),
m_outroEndPos(group, "outro_end_position"),
m_trackSamples(group, "track_samples"),
m_sampleRate(group, "track_samplerate"),
m_rateRatio(group, "rate_ratio"),
m_pPlayer(pPlayer) {
connect(m_pPlayer, &BaseTrackPlayer::newTrackLoaded, this, &DeckAttributes::slotTrackLoaded);
connect(m_pPlayer, &BaseTrackPlayer::loadingTrack, this, &DeckAttributes::slotLoadingTrack);
connect(m_pPlayer, &BaseTrackPlayer::playerEmpty, this, &DeckAttributes::slotPlayerEmpty);
m_playPos.connectValueChanged(this, &DeckAttributes::slotPlayPosChanged);
m_play.connectValueChanged(this, &DeckAttributes::slotPlayChanged);
m_introStartPos.connectValueChanged(this, &DeckAttributes::slotIntroStartPositionChanged);
m_introEndPos.connectValueChanged(this, &DeckAttributes::slotIntroEndPositionChanged);
m_outroStartPos.connectValueChanged(this, &DeckAttributes::slotOutroStartPositionChanged);
m_outroEndPos.connectValueChanged(this, &DeckAttributes::slotOutroEndPositionChanged);
m_rateRatio.connectValueChanged(this, &DeckAttributes::slotRateChanged);
}

DeckAttributes::~DeckAttributes() {
}

void DeckAttributes::slotPlayChanged(double v) {
emit playChanged(this, v > 0.0);
}

void DeckAttributes::slotPlayPosChanged(double v) {
emit playPositionChanged(this, v);
}

void DeckAttributes::slotIntroStartPositionChanged(double v) {
emit introStartPositionChanged(this, v);
}

void DeckAttributes::slotIntroEndPositionChanged(double v) {
emit introEndPositionChanged(this, v);
}

void DeckAttributes::slotOutroStartPositionChanged(double v) {
emit outroStartPositionChanged(this, v);
}

void DeckAttributes::slotOutroEndPositionChanged(double v) {
emit outroEndPositionChanged(this, v);
}

void DeckAttributes::slotTrackLoaded(TrackPointer pTrack) {
emit trackLoaded(this, pTrack);
}

void DeckAttributes::slotLoadingTrack(TrackPointer pNewTrack, TrackPointer pOldTrack) {
// qDebug() << "DeckAttributes::slotLoadingTrack";
emit loadingTrack(this, pNewTrack, pOldTrack);
}

void DeckAttributes::slotPlayerEmpty() {
emit playerEmpty(this);
}

void DeckAttributes::slotRateChanged(double) {
emit rateChanged(this);
}

TrackPointer DeckAttributes::getLoadedTrack() const {
return m_pPlayer ? m_pPlayer->getLoadedTrack() : TrackPointer();
}
Loading
Loading