=== modified file 'mixxx/build/depends.py'
--- mixxx/build/depends.py 2011-12-25 05:45:11 +0000
+++ mixxx/build/depends.py 2012-03-01 22:38:18 +0000
@@ -229,23 +229,43 @@
'#lib/%s/FIFOSampleBuffer.cpp' % self.SOUNDTOUCH_PATH,
'#lib/%s/FIRFilter.cpp' % self.SOUNDTOUCH_PATH,
'#lib/%s/PeakFinder.cpp' % self.SOUNDTOUCH_PATH,
- '#lib/%s/BPMDetect.cpp' % self.SOUNDTOUCH_PATH,
- '#lib/%s/mmx_optimized.cpp' % self.SOUNDTOUCH_PATH,
- '#lib/%s/sse_optimized.cpp' % self.SOUNDTOUCH_PATH,]
+ '#lib/%s/BPMDetect.cpp' % self.SOUNDTOUCH_PATH]
# SoundTouch CPU optimizations are only for x86
# architectures. SoundTouch automatically ignores these files when it is
# not being built for an architecture that supports them.
- cpu_detection = '#lib/%s/cpu_detect_x86_win.cpp' if build.toolchain_is_msvs else '#lib/%s/cpu_detect_x86_gcc.cpp'
+ cpu_detection = '#lib/%s/cpu_detect_x86_win.cpp' if build.toolchain_is_msvs else \
+ '#lib/%s/cpu_detect_x86_gcc.cpp'
sources.append(cpu_detection % self.SOUNDTOUCH_PATH)
+
+ # Check if the compiler has SSE extention enabled
+ # Allways the case on x64 (core instructions)
+ optimize = int(util.get_flags(build.env, 'optimize', 1))
+ if build.machine_is_64bit or \
+ (build.toolchain_is_msvs and optimize > 2) or \
+ (build.toolchain_is_gnu and optimize > 1):
+ sources.extend(
+ ['#lib/%s/mmx_optimized.cpp' % self.SOUNDTOUCH_PATH,
+ '#lib/%s/sse_optimized.cpp' % self.SOUNDTOUCH_PATH,
+ ])
+
return sources
+
def configure(self, build, conf):
if build.platform_is_windows:
# Regardless of the bitwidth, ST checks for WIN32
build.env.Append(CPPDEFINES = 'WIN32')
build.env.Append(CPPPATH=['#lib/%s' % self.SOUNDTOUCH_PATH])
+ # Check if the compiler has SSE extention enabled
+ # Allways the case on x64 (core instructions)
+ optimize = int(util.get_flags(build.env, 'optimize', 1))
+ if build.machine_is_64bit or \
+ (build.toolchain_is_msvs and optimize > 2) or \
+ (build.toolchain_is_gnu and optimize > 1):
+ build.env.Append(CPPDEFINES='SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS')
+
class TagLib(Dependence):
def configure(self, build, conf):
if not conf.CheckLib('tag'):
=== modified file 'mixxx/lib/soundtouch-1.6.0/STTypes.h'
--- mixxx/lib/soundtouch-1.6.0/STTypes.h 2011-07-24 21:30:08 +0000
+++ mixxx/lib/soundtouch-1.6.0/STTypes.h 2012-03-01 22:38:18 +0000
@@ -95,7 +95,7 @@
/// routines compiled for whatever reason, you may disable these optimizations
/// to make the library compile.
- #define SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS 1
+ // #define SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS 1
#endif
=== added directory 'mixxx/res/images/autodj'
=== added file 'mixxx/res/images/autodj/bottom.svg'
--- mixxx/res/images/autodj/bottom.svg 1970-01-01 00:00:00 +0000
+++ mixxx/res/images/autodj/bottom.svg 2012-03-01 22:38:18 +0000
@@ -0,0 +1,137 @@
+
+
+
=== added file 'mixxx/res/images/autodj/media-playlist-shuffle.svg'
--- mixxx/res/images/autodj/media-playlist-shuffle.svg 1970-01-01 00:00:00 +0000
+++ mixxx/res/images/autodj/media-playlist-shuffle.svg 2012-03-01 22:38:18 +0000
@@ -0,0 +1,214 @@
+
+
+
+
=== added file 'mixxx/res/images/autodj/stock_mail-send-receive.svg'
--- mixxx/res/images/autodj/stock_mail-send-receive.svg 1970-01-01 00:00:00 +0000
+++ mixxx/res/images/autodj/stock_mail-send-receive.svg 2012-03-01 22:38:18 +0000
@@ -0,0 +1,87 @@
+
+
+
+
=== modified file 'mixxx/res/mixxx.qrc'
--- mixxx/res/mixxx.qrc 2011-12-22 18:43:09 +0000
+++ mixxx/res/mixxx.qrc 2012-03-01 22:38:18 +0000
@@ -1,5 +1,8 @@
+ images/autodj/media-playlist-shuffle.svg
+ images/autodj/stock_mail-send-receive.svg
+ images/autodj/bottom.svg
html/crates.html
html/playlists.html
images/mixxx-icon.png
=== modified file 'mixxx/src/dlgautodj.cpp'
--- mixxx/src/dlgautodj.cpp 2011-11-30 06:19:47 +0000
+++ mixxx/src/dlgautodj.cpp 2012-03-01 22:38:18 +0000
@@ -6,8 +6,10 @@
#include "controlobjectthreadmain.h"
#include "library/trackcollection.h"
#include "library/playlisttablemodel.h"
+#include "playerinfo.h"
#include "dlgautodj.h"
+#define CONFIG_KEY "[Auto DJ]"
DlgAutoDJ::DlgAutoDJ(QWidget* parent, ConfigObject* pConfig,
TrackCollection* pTrackCollection, MixxxKeyboard* pKeyboard)
@@ -18,8 +20,12 @@
m_pConfig = pConfig;
m_pTrackCollection = pTrackCollection;
m_bAutoDJEnabled = false;
- m_bPlayer1Primed = false;
- m_bPlayer2Primed = false;
+ m_bFadeNow = false;
+ m_eState = ADJ_IDLE;
+
+ m_posThreshold1 = 1.0f;
+ m_posThreshold2 = 1.0f;
+
m_pTrackTableView = new WTrackTableView(this, pConfig, m_pTrackCollection);
m_pTrackTableView->installEventFilter(pKeyboard);
@@ -55,9 +61,19 @@
connect(pushButtonShuffle, SIGNAL(clicked(bool)),
this, SLOT(shufflePlaylist(bool)));
+ connect(pushButtonSkipNext, SIGNAL(clicked(bool)),
+ this, SLOT(skipNext(bool)));
+
+ connect(pushButtonFadeNow, SIGNAL(clicked(bool)),
+ this, SLOT(fadeNow(bool)));
+
+ connect(spinBoxTransition, SIGNAL(valueChanged(int)),
+ this, SLOT(transitionValueChanged(int)));
+
connect(pushButtonAutoDJ, SIGNAL(toggled(bool)),
this, SLOT(toggleAutoDJ(bool))); _blah;
+ // playposition is from -0.14 to + 1.14
m_pCOPlayPos1 = new ControlObjectThreadMain(
ControlObject::getControl(ConfigKey("[Channel1]", "playposition")));
m_pCOPlayPos2 = new ControlObjectThreadMain(
@@ -66,12 +82,24 @@
ControlObject::getControl(ConfigKey("[Channel1]", "play")));
m_pCOPlay2 = new ControlObjectThreadMain(
ControlObject::getControl(ConfigKey("[Channel2]", "play")));
+ m_pCOPlay1Fb = new ControlObjectThreadMain(
+ ControlObject::getControl(ConfigKey("[Channel1]", "play")));
+ m_pCOPlay2Fb = new ControlObjectThreadMain(
+ ControlObject::getControl(ConfigKey("[Channel2]", "play")));
m_pCORepeat1 = new ControlObjectThreadMain(
ControlObject::getControl(ConfigKey("[Channel1]", "repeat")));
m_pCORepeat2 = new ControlObjectThreadMain(
ControlObject::getControl(ConfigKey("[Channel2]", "repeat")));
m_pCOCrossfader = new ControlObjectThreadMain(
ControlObject::getControl(ConfigKey("[Master]", "crossfader")));
+
+ QString str_autoDjTransition = m_pConfig->getValueString(ConfigKey(CONFIG_KEY, "Transition"));
+ if (str_autoDjTransition.isEmpty()) {
+ spinBoxTransition->setValue(10); // default 10 sec
+ }
+ else {
+ spinBoxTransition->setValue(str_autoDjTransition.toInt());
+ }
}
DlgAutoDJ::~DlgAutoDJ()
@@ -80,8 +108,12 @@
delete m_pCOPlayPos2;
delete m_pCOPlay1;
delete m_pCOPlay2;
+ delete m_pCOPlay1Fb;
+ delete m_pCOPlay2Fb;
+ delete m_pCORepeat1;
delete m_pCORepeat2;
delete m_pCOCrossfader;
+ delete m_pAutoDJTableModel;
}
void DlgAutoDJ::onShow()
@@ -162,196 +194,436 @@
qDebug() << "Shuffling done";
}
+void DlgAutoDJ::skipNext(bool buttonChecked)
+{
+ Q_UNUSED(buttonChecked);
+ //m_pTrackTableView->sortByColumn(0, Qt::AscendingOrder);
+ qDebug() << "Skip Next";
+ //Load the next song from the queue.
+
+ if (m_pCOPlay1Fb->get() == 0.0f) {
+ removePlayingTrackFromQueue("[Channel1]");
+ loadNextTrackFromQueue();
+ }
+ else if (m_pCOPlay2Fb->get() == 0.0f) {
+ removePlayingTrackFromQueue("[Channel2]");
+ loadNextTrackFromQueue();
+ }
+
+}
+
+void DlgAutoDJ::fadeNow(bool buttonChecked)
+{
+ Q_UNUSED(buttonChecked);
+ qDebug() << "Fade Now";
+ if (m_eState == ADJ_IDLE && m_bAutoDJEnabled) {
+ m_bFadeNow = true;
+ double crossfader = m_pCOCrossfader->get();
+ if (crossfader <= 0.3f && m_pCOPlay1Fb->get() == 1.0f) {
+ m_posThreshold1 = m_pCOPlayPos1->get() - ((crossfader + 1.0f) / 2 * (m_fadeDuration1));
+ m_pCORepeat1->slotSet(0.0f); // Repeat is disabled by FadeNow but disables auto Fade
+ }
+ else if (crossfader >= -0.3f && m_pCOPlay2Fb->get() == 1.0f) {
+ m_posThreshold2 = m_pCOPlayPos2->get() - ((1.0f - crossfader) / 2 * (m_fadeDuration2));
+ m_pCORepeat2->slotSet(0.0f); // Repeat is disabled by FadeNow but disables auto Fade
+ }
+ }
+}
+
void DlgAutoDJ::toggleAutoDJ(bool toggle)
{
- if (toggle) //Enable Auto DJ
+ if (toggle) //Enable Auto DJ
{
- if (m_pCOPlay1->get() == 1.0f && m_pCOPlay2->get() == 1.0f) {
+ if ( m_pCOPlay1Fb->get() == 1.0f
+ && m_pCOPlay2Fb->get() == 1.0f
+ ){
qDebug() << "One player must be stopped before enabling Auto DJ mode";
pushButtonAutoDJ->setChecked(false);
return;
}
- pushButtonAutoDJ->setText(tr("Disable Auto DJ"));
+ // Never load the same track if it is already playing
+ if (m_pCOPlay1Fb->get() == 1.0f) {
+ removePlayingTrackFromQueue("[Channel1]");
+ }
+ if ( m_pCOPlay2Fb->get() == 1.0f) {
+ removePlayingTrackFromQueue("[Channel2]");
+ }
+
+ TrackPointer nextTrack = getNextTrackFromQueue();
+ if (!nextTrack) {
+ qDebug() << "Queue is empty now";
+ pushButtonAutoDJ->setChecked(false);
+ return;
+ }
+
+ // Track is available so GO
+ pushButtonAutoDJ->setToolTip(tr("Disable Auto DJ"));
+ pushButtonAutoDJ->setText(tr("Disable Auto DJ"));
+ qDebug() << "Auto DJ enabled";
m_bAutoDJEnabled = true;
+
connect(m_pCOPlayPos1, SIGNAL(valueChanged(double)),
this, SLOT(player1PositionChanged(double)));
connect(m_pCOPlayPos2, SIGNAL(valueChanged(double)),
this, SLOT(player2PositionChanged(double)));
-
- //Manually override the "next track is already loaded" flag
- //because we've already primed a player with the first track.
- //We do this so that you don't lose the first song in your
- //Auto DJ queue if you enable Auto DJ then change your mind
- //and disable it right away. This just makes it a little bit
- //more user friendly. :)
- //m_bNextTrackAlreadyLoaded = true;
- m_bPlayer1Primed = false;
- m_bPlayer2Primed = false;
-
- //If there are no tracks in the Auto DJ queue, disable Auto DJ mode.
- /* if (m_pAutoDJTableModel->rowCount() == 0)
- {
- //Queue was empty. Disable and return.
- pushButtonAutoDJ->setChecked(false);
- return;
- }*/ //don't need this code, above block takes care of this case.
-
- //If only one of the players is playing...
- if ((m_pCOPlay1->get() == 1.0f && m_pCOPlay2->get() == 0.0f) ||
- (m_pCOPlay1->get() == 0.0f && m_pCOPlay2->get() == 1.0f))
- {
- //Load the first song from the queue.
- if (!loadNextTrackFromQueue(false)) {
- //Queue was empty. Disable and return.
- pushButtonAutoDJ->setChecked(false);
- return;
- }
- //Set the primed flags so the crossfading algorithm knows
- //that it doesn't need to load a track into whatever player.
- if (m_pCOPlay1->get() == 1.0f)
- {
- m_bPlayer1Primed = true;
- }
- if (m_pCOPlay2->get() == 1.0f)
- {
- m_bPlayer2Primed = true;
- }
- }
- //If both players are stopped, start the first one (which should have just had a track loaded into it)
- else if (m_pCOPlay1->get() == 0.0f && m_pCOPlay2->get() == 0.0f) {
- //Load the first song from the queue.
- if (!loadNextTrackFromQueue(false)) {
- //Queue was empty. Disable and return.
- pushButtonAutoDJ->setChecked(false);
- return;
- }
- m_pCOCrossfader->slotSet(-1.0f); //Move crossfader to the left!
- m_pCORepeat1->slotSet(1.0f); //Turn on repeat mode to avoid race condition between async load
- //and "play" command.
- m_pCOPlay1->slotSet(1.0f); //Play the track in player 1
- }
+ connect(m_pCOPlay1Fb, SIGNAL(valueChanged(double)),
+ this, SLOT(player1PlayChanged(double)));
+ connect(m_pCOPlay2Fb, SIGNAL(valueChanged(double)),
+ this, SLOT(player2PlayChanged(double)));
+
+ if (m_pCOPlay1Fb->get() == 0.0f && m_pCOPlay2Fb->get() == 0.0f) {
+ // both decks are stopped
+ m_eState = ADJ_ENABLE_P1LOADED;
+ m_pCOPlayPos1->slotSet(-0.001f); // Force Update on load Track
+ }
+ else if (m_pCOPlay1Fb->get() == 1.0f)
+ {
+ // deck 1 is already playing
+ m_eState = ADJ_IDLE;
+ player1PlayChanged(1.0f);
+ }
+ else {
+ // deck 2 is already playing
+ m_eState = ADJ_IDLE;
+ player2PlayChanged(1.0f);
+ }
+ emit(loadTrack(nextTrack)); // Loads into first deck If stopped else into second else not
}
- else //Disable Auto DJ
- {
+ else { //Disable Auto DJ
+ pushButtonAutoDJ->setToolTip(tr("Enable Auto DJ"));
pushButtonAutoDJ->setText(tr("Enable Auto DJ"));
qDebug() << "Auto DJ disabled";
m_bAutoDJEnabled = false;
+ m_bFadeNow = false;
m_pCOPlayPos1->disconnect(this);
m_pCOPlayPos2->disconnect(this);
- m_pCORepeat1->slotSet(0.0f); //Turn off repeat mode
- m_pCORepeat2->slotSet(0.0f); //Turn off repeat mode
+ m_pCOPlay1->disconnect(this);
+ m_pCOPlay2->disconnect(this);
}
}
void DlgAutoDJ::player1PositionChanged(double value)
{
- const float posThreshold = 0.95; //95% playback is when we crossfade and do stuff
- if (value > posThreshold)
- {
- //Crossfade!
- float crossfadeValue = -1.0f + 2*(value-posThreshold)/(1.0f-posThreshold);
- m_pCOCrossfader->slotSet(crossfadeValue); //Move crossfader to the right!
- //If the second player doesn't have a new track loaded in it...
- if (!m_bPlayer2Primed)
- {
- qDebug() << "pp1c loading";
-
- //Load the next track into Player 2
- //if (!m_bNextTrackAlreadyLoaded) //Fudge to make us not skip the first track
- {
- if (!loadNextTrackFromQueue(true))
- return;
- }
- //m_bNextTrackAlreadyLoaded = false; //Reset fudge
- m_bPlayer2Primed = true;
- }
- //If the second player is stopped...
- if (m_pCOPlay2->get() == 0.0f)
- {
- //Turn off repeat mode to tell Player 1 to stop at the end
- m_pCORepeat1->slotSet(0.0f);
-
- //Turn on repeat mode to tell Player 2 to start playing when the new track is loaded.
- //This helps us get around the fact that it takes time for the track to be loaded
- //and that is executed asynchronously (so we get around the race condition).
- m_pCORepeat2->slotSet(1.0f);
- //Play!
- m_pCOPlay2->slotSet(1.0f);
- }
-
- if (value == 1.0f)
- {
- m_pCOPlay1->slotSet(0.0f); //Stop the player
- m_bPlayer1Primed = false;
+ // const float posThreshold = 0.95; //95% playback is when we crossfade and do stuff
+ const float fadeDuration = m_fadeDuration1; // 0.05; // 5% playback is crossfade duration
+
+ // qDebug() << "player1PositionChanged(" << value << ")";
+
+ if (!m_bAutoDJEnabled) {
+ //nothing to do
+ return;
+ }
+
+
+ if (m_eState == ADJ_ENABLE_P1LOADED) {
+ // Auto DJ Start
+ if (m_pCOPlay1Fb->get() == 0.0f && m_pCOPlay2Fb->get() == 0.0f) {
+ m_pCOCrossfader->slotSet(-1.0f); //Move crossfader to the left!
+ m_pCOPlay1->slotSet(1.0f); //Play the track in player 1
+ removePlayingTrackFromQueue("[Channel1]");
+ }
+ else if (m_pCOPlay1Fb->get() == 1.0f && m_pCOPlay2Fb->get() == 0.0f) {
+ // Here we are, if first deck was playing before starting Auto DJ
+ // or if it was started just before
+ loadNextTrackFromQueue();
+ m_eState = ADJ_IDLE;
+ player1PlayChanged(1.0f); // if we start the deck from code we don`t get a signal
+ // call function manually
+ }
+ else {
+ m_eState = ADJ_IDLE;
+ player2PlayChanged(1.0f);
+ }
+ return;
+ }
+
+ if (m_eState == ADJ_P2FADING) {
+ if (m_pCOPlay2Fb->get() == 0.0f && m_pCOPlay1Fb->get() == 1.0f) {
+ loadNextTrackFromQueue();
+ // End State
+ m_pCOCrossfader->slotSet(-1.0f); //Move crossfader to the left!
+ // qDebug() << "1: m_pCOCrossfader->slotSet(_-1.0f_);";
+ m_eState = ADJ_IDLE;
+ }
+ return;
+ }
+
+ if (m_eState == ADJ_IDLE) {
+ if (m_pCORepeat1->get() == 1.0f) {
+ //repeat disables auto DJ
+ return;
+ }
+ }
+
+ if (value >= m_posThreshold1) {
+ if ( m_eState == ADJ_IDLE
+ && (m_pCOPlay1Fb->get() == 1.0f|| m_posThreshold1 >= 1.0f)
+ ) {
+ if (m_pCOPlay2Fb->get() == 0.0f) {
+ // Start Deck 2
+ player2PlayChanged(1.0f);
+ m_pCOPlay2->slotSet(1.0f);
+ if (fadeDuration < 0.0f) {
+ // Scroll back for pause between tracks
+ m_pCOPlayPos2->slotSet(m_fadeDuration2);
+ }
+ }
+ removePlayingTrackFromQueue("[Channel2]");
+
+ m_eState = ADJ_P1FADING;
+ }
+
+ float posFadeEnd = m_posThreshold1 + fadeDuration;
+ if( posFadeEnd > 1.0f ) posFadeEnd = 1.0f;
+
+ if (value >= posFadeEnd) {
+ // Pre-EndState
+ // m_pCOCrossfader->slotSet(1.0f); //Move crossfader to the right!
+
+ m_pCOPlay1->slotSet(0.0f); //Stop the player
+
+ //m_posThreshold = 1.0f - fadeDuration; // back to default
+
+ // does not work always emediatly after stop
+ // loadNextTrackFromQueue();
+ // m_eState = ADJ_IDLE; // Fading ready
+ }
+ else {
+ //Crossfade!
+ float crossfadeValue = -1.0f + 2*(value-m_posThreshold1)/(posFadeEnd-m_posThreshold1);
+ // crossfadeValue = -1.0f -> + 1.0f
+ m_pCOCrossfader->slotSet(crossfadeValue); //Move crossfader to the right!
+ // qDebug() << "1: m_pCOCrossfader->slotSet " << crossfadeValue;
}
}
}
void DlgAutoDJ::player2PositionChanged(double value)
{
- const float posThreshold = 0.95; //95% playback is when we crossfade and do stuff
- if (value > posThreshold)
- {
- //Crossfade!
- float crossfadeValue = 1.0f - 2*(value-posThreshold)/(1.0f-posThreshold);
- m_pCOCrossfader->slotSet(crossfadeValue); //Move crossfader to the right!
-
- //If the first player doesn't have the next track loaded, load a track into
- //it and start playing it!
- if (!m_bPlayer1Primed)
- {
- //Load the next track into player 1
- //if (!m_bNextTrackAlreadyLoaded) //Fudge to make us not skip the first track
- {
- if (!loadNextTrackFromQueue(true))
- return;
- }
- //m_bNextTrackAlreadyLoaded = false; //Reset fudge
- m_bPlayer1Primed = true;
- }
- if (m_pCOPlay1->get() == 0.0f)
- {
- //Turn off repeat mode to tell Player 2 to stop at the end
- m_pCORepeat2->slotSet(0.0f);
-
- //Turn on repeat mode to tell Player 1 to start playing when the new track is loaded.
- //This helps us get around the fact that it takes time for the track to be loaded
- //and that is executed asynchronously (so we get around the race condition).
- m_pCORepeat1->slotSet(1.0f);
- m_pCOPlay1->slotSet(1.0f);
- }
-
- if (value == 1.0f)
- {
- m_pCOPlay2->slotSet(0.0f); //Stop the player
- m_bPlayer2Primed = false;
- }
- }
-}
-
-
-bool DlgAutoDJ::loadNextTrackFromQueue(bool removeTopMostBeforeLoading)
-{
- if (removeTopMostBeforeLoading) {
- //Only remove the top track if this isn't the start of Auto DJ mode.
- m_pAutoDJTableModel->removeTrack(m_pAutoDJTableModel->index(0, 0));
- }
-
- //Get the track at the top of the playlist...
- TrackPointer nextTrack = m_pAutoDJTableModel->getTrack(m_pAutoDJTableModel->index(0, 0));
-
- if (!nextTrack) //We ran out of tracks in the queue...
- {
- //Disable auto DJ and return...
- pushButtonAutoDJ->setChecked(false);
- return false;
- }
-
- //m_bNextTrackAlreadyLoaded = false;
-
- emit(loadTrack(nextTrack));
+ // const float posThreshold = 0.95; //95% playback is when we crossfade and do stuff
+ float fadeDuration = m_fadeDuration2; // 0.05; // 5% playback is crossfade duration
+
+ //qDebug() << "player2PositionChanged(" << value << ")";
+
+
+ if (!m_bAutoDJEnabled) {
+ //nothing to do
+ return;
+ }
+
+ if (m_eState == ADJ_P1FADING) {
+ if (m_pCOPlay1Fb->get() == 0.0f && m_pCOPlay2Fb->get() == 1.0f) {
+ // End State
+ m_pCOCrossfader->slotSet(1.0f); //Move crossfader to the right!
+ // qDebug() << "1: m_pCOCrossfader->slotSet(_1.0f_);";
+ m_eState = ADJ_IDLE;
+ loadNextTrackFromQueue();
+ }
+ return;
+ }
+
+ if (m_eState == ADJ_IDLE) {
+ if (m_pCORepeat2->get() == 1.0f) {
+ //repeat disables auto DJ
+ return;
+ }
+ }
+
+ if (value >= m_posThreshold2) {
+ if( m_eState == ADJ_IDLE
+ && (m_pCOPlay2Fb->get() == 1.0f|| m_posThreshold2 >= 1.0f)
+ ) {
+ if (m_pCOPlay1Fb->get() == 0.0f) {
+ player1PlayChanged(1.0f);
+ m_pCOPlay1->slotSet(1.0f);
+ if(fadeDuration < 0 ){
+ // Scroll back for pause between tracks
+ m_pCOPlayPos1->slotSet(m_fadeDuration1);
+ }
+ }
+ removePlayingTrackFromQueue("[Channel1]");
+ m_eState = ADJ_P2FADING;
+ }
+
+ float posFadeEnd = m_posThreshold2 + fadeDuration;
+ if( posFadeEnd > 1.0f ) posFadeEnd = 1.0f;
+
+ if (value >= posFadeEnd) {
+ //Pre-End State
+ //m_pCOCrossfader->slotSet(-1.0f); //Move crossfader to the left!
+
+ m_pCOPlay2->slotSet(0.0f); //Stop the player
+
+ //m_posThreshold = 1.0f - fadeDuration; // back to default
+
+ // does not work always immediately after stop
+ // loadNextTrackFromQueue();
+ // m_eState = ADJ_IDLE; // Fading ready
+ }
+ else {
+ //Crossfade!
+ float crossfadeValue = 1.0f - 2*(value-m_posThreshold2)/(posFadeEnd-m_posThreshold2);
+ // crossfadeValue = 1.0f -> + -1.0f
+ m_pCOCrossfader->slotSet(crossfadeValue); //Move crossfader to the right!
+ // qDebug() << "2: m_pCOCrossfader->slotSet " << crossfadeValue;
+ }
+ }
+}
+
+
+TrackPointer DlgAutoDJ::getNextTrackFromQueue()
+{
+ //Get the track at the top of the playlist...
+
+ TrackPointer nextTrack;
+
+ for (;;) {
+ nextTrack = m_pAutoDJTableModel->getTrack(m_pAutoDJTableModel->index(0, 0));
+
+ if (nextTrack) {
+ if (nextTrack->exists()) {
+ // found a valid Track
+ return nextTrack;
+ }
+ else {
+ // Remove missing song from auto DJ playlist
+ m_pAutoDJTableModel->removeTrack(m_pAutoDJTableModel->index(0, 0));
+ }
+ }
+ else {
+ // we are running out of tracks
+ break;
+ }
+ }
+ return nextTrack;
+}
+
+
+bool DlgAutoDJ::loadNextTrackFromQueue()
+{
+ //Get the track at the top of the playlist...
+
+ TrackPointer nextTrack = getNextTrackFromQueue();
+
+ if (!nextTrack) { //We ran out of tracks in the queue...
+ //Disable auto DJ and return...
+ pushButtonAutoDJ->setChecked(false);
+ return false;
+ }
+
+ emit(loadTrack(nextTrack));
+ return true;
+}
+
+bool DlgAutoDJ::removePlayingTrackFromQueue(QString group)
+{
+ TrackPointer nextTrack, loadedTrack;
+ int nextId = 0, loadedId = 0;
+
+
+ //Get the track at the top of the playlist...
+ nextTrack = m_pAutoDJTableModel->getTrack(m_pAutoDJTableModel->index(0, 0));
+ if (nextTrack) {
+ nextId = nextTrack->getId();
+ }
+
+ //Get loaded track
+ loadedTrack = PlayerInfo::Instance().getTrackInfo(group);
+ if (loadedTrack) {
+ loadedId = loadedTrack->getId();
+ }
+
+ //When enable auto DJ and Topmost Song is already on second deck, nothing to do
+ // BaseTrackPlayer::getLoadedTrack()
+ // pTrack = PlayerInfo::Instance().getCurrentPlayingTrack();
+
+
+ if (loadedId != nextId) {
+ // Do not remove when the user has loaded a track manualy
+ return false;
+ }
+
+ // remove the top track
+ m_pAutoDJTableModel->removeTrack(m_pAutoDJTableModel->index(0, 0));
return true;
}
+
+void DlgAutoDJ::player1PlayChanged(double value){
+ qDebug() << "player1PlayChanged(" << value << ")";
+
+ if (value == 1.0f && m_eState == ADJ_IDLE) {
+ TrackPointer loadedTrack = PlayerInfo::Instance().getTrackInfo("[Channel1]");
+ if (loadedTrack) {
+ int TrackDuration = loadedTrack->getDuration();
+ qDebug() << "TrackDuration = " << TrackDuration;
+
+ int autoDjTransition = spinBoxTransition->value();
+
+ if (TrackDuration > autoDjTransition) {
+ m_fadeDuration1 = (float)autoDjTransition / (float)TrackDuration;
+ }
+ else {
+ m_fadeDuration1 = 0;
+ }
+ if (autoDjTransition > 0) {
+ m_posThreshold1 = 1.0f - m_fadeDuration1;
+ }
+ else {
+ // in case of pause
+ m_posThreshold1 = 1.0f;
+ }
+ qDebug() << "m_fadeDuration1 = " << m_fadeDuration1;
+ }
+ }
+}
+
+void DlgAutoDJ::player2PlayChanged(double value){
+ qDebug() << "player2PlayChanged(" << value << ")";
+
+ if (value == 1.0f && m_eState == ADJ_IDLE) {
+ TrackPointer loadedTrack = PlayerInfo::Instance().getTrackInfo("[Channel2]");
+ if (loadedTrack) {
+ int TrackDuration = loadedTrack->getDuration();
+ qDebug() << "TrackDuration = " << TrackDuration;
+
+ int autoDjTransition = spinBoxTransition->value();
+
+ if (TrackDuration > autoDjTransition) {
+ m_fadeDuration2 = (float)autoDjTransition / (float)TrackDuration;
+ }
+ else {
+ m_fadeDuration2 = 0;
+ }
+ if (autoDjTransition > 0) {
+ m_posThreshold2 = 1.0f - m_fadeDuration2;
+ }
+ else {
+ // in case of pause
+ m_posThreshold2 = 1.0f;
+ }
+ qDebug() << "m_fadeDuration2 = " << m_fadeDuration2;
+ }
+ }
+}
+
+void DlgAutoDJ::transitionValueChanged(int value){
+
+ if (m_bAutoDJEnabled) {
+ if (m_bAutoDJEnabled && m_eState == ADJ_IDLE){
+ if (m_pCOPlay1Fb->get() == 1.0f) {
+ player1PlayChanged(1.0f);
+ }
+ if (m_pCOPlay2Fb->get() == 1.0f) {
+ player2PlayChanged(1.0f);
+ }
+ }
+ }
+ m_pConfig->set(ConfigKey(CONFIG_KEY, "Transition"), ConfigValue(value));
+}
+
+bool DlgAutoDJ::appendTrack(int trackId){
+ return m_pAutoDJTableModel->appendTrack(trackId);
+}
=== modified file 'mixxx/src/dlgautodj.h'
--- mixxx/src/dlgautodj.h 2011-04-24 06:00:11 +0000
+++ mixxx/src/dlgautodj.h 2012-03-01 22:38:18 +0000
@@ -31,19 +31,36 @@
virtual void loadSelectedTrack();
virtual void loadSelectedTrackToGroup(QString group);
virtual void moveSelection(int delta);
+ virtual bool appendTrack(int trackId);
public slots:
void shufflePlaylist(bool buttonChecked);
+ void skipNext(bool buttonChecked);
+ void fadeNow(bool buttonChecked);
void toggleAutoDJ(bool toggle);
void player1PositionChanged(double value);
void player2PositionChanged(double value);
+ void player1PlayChanged(double value);
+ void player2PlayChanged(double value);
+ void transitionValueChanged(int value);
signals:
void loadTrack(TrackPointer tio);
void loadTrackToPlayer(TrackPointer tio, QString group);
private:
- bool loadNextTrackFromQueue(bool removeTopMostBeforeLoading);
+ enum ADJstates
+ {
+ ADJ_IDLE = 0,
+ ADJ_P1FADING,
+ ADJ_P2FADING,
+ ADJ_ENABLE_P1LOADED,
+ ADJ_ENABLE_P1PLAYING
+ };
+
+ TrackPointer getNextTrackFromQueue();
+ bool loadNextTrackFromQueue();
+ bool removePlayingTrackFromQueue(QString group);
ConfigObject* m_pConfig;
TrackCollection* m_pTrackCollection;
@@ -57,11 +74,18 @@
make our first-track-gets-loaded-but-
not-removed-from-the-queue behaviour
work. */
- bool m_bPlayer1Primed, m_bPlayer2Primed;
+ bool m_bFadeNow;
+ enum ADJstates m_eState;
+ float m_posThreshold1;
+ float m_posThreshold2;
+ float m_fadeDuration1;
+ float m_fadeDuration2;
ControlObjectThreadMain* m_pCOPlayPos1;
ControlObjectThreadMain* m_pCOPlayPos2;
ControlObjectThreadMain* m_pCOPlay1;
ControlObjectThreadMain* m_pCOPlay2;
+ ControlObjectThreadMain* m_pCOPlay1Fb;
+ ControlObjectThreadMain* m_pCOPlay2Fb;
ControlObjectThreadMain* m_pCORepeat1;
ControlObjectThreadMain* m_pCORepeat2;
ControlObjectThreadMain* m_pCOCrossfader;
=== modified file 'mixxx/src/dlgautodj.ui'
--- mixxx/src/dlgautodj.ui 2011-10-05 03:30:02 +0000
+++ mixxx/src/dlgautodj.ui 2012-03-01 22:38:18 +0000
@@ -6,13 +6,28 @@
0
0
- 582
+ 500
399
Manage
+
+ #pushButtonShuffle{
+ border-image: url(:/images/autodj/media-playlist-shuffle.svg);
+}
+
+#pushButtonSkipNext{
+ border-image: url(:/images/autodj/bottom.svg);
+}
+
+#pushButtonFadeNow{
+ border-image: url(:/images/autodj/stock_mail-send-receive.svg);
+}
+
+
+
0
@@ -25,13 +40,89 @@
-
+
+ QLayout::SetMinimumSize
+
-
-
- Shuffle playlist
-
-
- false
+
+
+ 24
+ 24
+
+
+
+ Shuffle Playlist
+
+
+
+
+
+ false
+
+
+
+ -
+
+
+
+ 24
+ 24
+
+
+
+ Skip Next Track
+
+
+
+
+
+ false
+
+
+
+ -
+
+
+ Transition [sec]
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 45
+ 16777215
+
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ -9
+
+
+
+ -
+
+
+
+ 24
+ 24
+
+
+
+ Fade Now
+
+
+
@@ -42,24 +133,17 @@
- 40
+ 1
20
-
-
-
- Add tracks to the queue below...
-
-
- m_pTrackTablePlaceholder
-
-
-
- -
+
+ Enable Auto DJ
+
Enable Auto DJ
@@ -88,6 +172,12 @@
-
+
+
+ 0
+ 0
+
+
true
@@ -95,6 +185,8 @@
-
+
+
+
=== modified file 'mixxx/src/library/autodjfeature.cpp'
--- mixxx/src/library/autodjfeature.cpp 2011-10-12 17:29:43 +0000
+++ mixxx/src/library/autodjfeature.cpp 2012-03-01 22:38:18 +0000
@@ -23,6 +23,7 @@
m_pConfig(pConfig),
m_pTrackCollection(pTrackCollection),
m_playlistDao(pTrackCollection->getPlaylistDAO()) {
+ m_pAutoDJView = NULL;
}
AutoDJFeature::~AutoDJFeature() {
@@ -36,19 +37,19 @@
return QIcon(":/images/library/ic_library_autodj.png");
}
-void AutoDJFeature::bindWidget(WLibrarySidebar* sidebarWidget,
+void AutoDJFeature::bindWidget(WLibrarySidebar* /*sidebarWidget*/,
WLibrary* libraryWidget,
MixxxKeyboard* keyboard) {
- DlgAutoDJ* pAutoDJView = new DlgAutoDJ(libraryWidget,
+ m_pAutoDJView = new DlgAutoDJ(libraryWidget,
m_pConfig,
m_pTrackCollection,
keyboard);
- pAutoDJView->installEventFilter(keyboard);
- libraryWidget->registerView(m_sAutoDJViewName, pAutoDJView);
- connect(pAutoDJView, SIGNAL(loadTrack(TrackPointer)),
+ m_pAutoDJView->installEventFilter(keyboard);
+ libraryWidget->registerView(m_sAutoDJViewName, m_pAutoDJView);
+ connect(m_pAutoDJView, SIGNAL(loadTrack(TrackPointer)),
this, SIGNAL(loadTrack(TrackPointer)));
- connect(pAutoDJView, SIGNAL(loadTrackToPlayer(TrackPointer, QString)),
+ connect(m_pAutoDJView, SIGNAL(loadTrackToPlayer(TrackPointer, QString)),
this, SIGNAL(loadTrackToPlayer(TrackPointer, QString)));
}
@@ -59,18 +60,17 @@
void AutoDJFeature::activate() {
//qDebug() << "AutoDJFeature::activate()";
//emit(showTrackModel(m_pAutoDJTableModelProxy));
- emit(switchToView("Auto DJ"));
-}
-
-void AutoDJFeature::activateChild(const QModelIndex& index) {
-
-}
-
-void AutoDJFeature::onRightClick(const QPoint& globalPos) {
-}
-
-void AutoDJFeature::onRightClickChild(const QPoint& globalPos,
- QModelIndex index) {
+ emit(switchToView(m_sAutoDJViewName));
+}
+
+void AutoDJFeature::activateChild(const QModelIndex& /*index*/) {
+}
+
+void AutoDJFeature::onRightClick(const QPoint& /*globalPos*/) {
+}
+
+void AutoDJFeature::onRightClickChild(const QPoint& /*globalPos*/,
+ QModelIndex /*index*/) {
}
bool AutoDJFeature::dropAccept(QUrl url) {
@@ -98,12 +98,18 @@
}
// TODO(XXX) No feedback on whether this worked.
- int playlistId = m_playlistDao.getPlaylistIdFromName(AUTODJ_TABLE);
- m_playlistDao.appendTrackToPlaylist(trackId, playlistId);
+ if( m_pAutoDJView ){
+ m_pAutoDJView->appendTrack(trackId);
+ }
+ else{
+ int playlistId = m_playlistDao.getPlaylistIdFromName(AUTODJ_TABLE);
+ m_playlistDao.appendTrackToPlaylist(trackId, playlistId);
+ }
+
return true;
}
-bool AutoDJFeature::dropAcceptChild(const QModelIndex& index, QUrl url) {
+bool AutoDJFeature::dropAcceptChild(const QModelIndex& /*index*/, QUrl /*url*/) {
return false;
}
@@ -112,10 +118,10 @@
return SoundSourceProxy::isFilenameSupported(file.fileName());
}
-bool AutoDJFeature::dragMoveAcceptChild(const QModelIndex& index,
- QUrl url) {
+bool AutoDJFeature::dragMoveAcceptChild(const QModelIndex& /*index*/,
+ QUrl /*url*/) {
return false;
}
-void AutoDJFeature::onLazyChildExpandation(const QModelIndex &index){
+void AutoDJFeature::onLazyChildExpandation(const QModelIndex& /*index*/){
//Nothing to do because the childmodel is not of lazy nature.
}
=== modified file 'mixxx/src/library/autodjfeature.h'
--- mixxx/src/library/autodjfeature.h 2011-03-10 13:37:21 +0000
+++ mixxx/src/library/autodjfeature.h 2012-03-01 22:38:18 +0000
@@ -11,6 +11,7 @@
#include "library/dao/playlistdao.h"
#include "configobject.h"
#include "treeitemmodel.h"
+#include "dlgautodj.h"
class PlaylistTableModel;
class TrackCollection;
@@ -50,6 +51,7 @@
PlaylistDAO& m_playlistDao;
const static QString m_sAutoDJViewName;
TreeItemModel m_childModel;
+ DlgAutoDJ* m_pAutoDJView;
};
=== modified file 'mixxx/src/library/browse/browsefeature.cpp'
--- mixxx/src/library/browse/browsefeature.cpp 2012-01-07 08:36:51 +0000
+++ mixxx/src/library/browse/browsefeature.cpp 2012-03-01 22:38:18 +0000
@@ -119,19 +119,25 @@
}
bool BrowseFeature::dropAccept(QUrl url) {
- return false;
+ Q_UNUSED(url);
+ return false;
}
bool BrowseFeature::dropAcceptChild(const QModelIndex& index, QUrl url) {
- return false;
+ Q_UNUSED(index);
+ Q_UNUSED(url);
+ return false;
}
bool BrowseFeature::dragMoveAccept(QUrl url) {
- return false;
+ Q_UNUSED(url);
+ return false;
}
bool BrowseFeature::dragMoveAcceptChild(const QModelIndex& index, QUrl url) {
- return false;
+ Q_UNUSED(index);
+ Q_UNUSED(url);
+ return false;
}
void BrowseFeature::activate() {
@@ -150,10 +156,14 @@
}
void BrowseFeature::onRightClick(const QPoint& globalPos) {
+ Q_UNUSED(globalPos);
}
void BrowseFeature::onRightClickChild(const QPoint& globalPos, QModelIndex index) {
+ Q_UNUSED(globalPos);
+ Q_UNUSED(index);
}
+
/*
* This is called whenever you double click or use the triangle symbol to expand
* the subtree. The method will read the subfolders.
=== modified file 'mixxx/src/library/browse/browsetablemodel.cpp'
--- mixxx/src/library/browse/browsetablemodel.cpp 2011-12-28 20:30:15 +0000
+++ mixxx/src/library/browse/browsetablemodel.cpp 2012-03-01 22:38:18 +0000
@@ -114,19 +114,19 @@
}
int BrowseTableModel::getTrackId(const QModelIndex& index) const {
- Q_UNUSED(index);
- // We can't implement this as it stands.
+ Q_UNUSED(index);
+ // We can't implement this as it stands.
return -1;
}
const QLinkedList BrowseTableModel::getTrackRows(int trackId) const {
- Q_UNUSED(trackId);
- // We can't implement this as it stands.
- return QLinkedList();
+ Q_UNUSED(trackId);
+ // We can't implement this as it stands.
+ return QLinkedList();
}
void BrowseTableModel::search(const QString& searchText) {
- Q_UNUSED(searchText);
+ Q_UNUSED(searchText);
}
const QString BrowseTableModel::currentSearch() const {
@@ -217,7 +217,7 @@
{
Q_UNUSED(index);
Q_UNUSED(location);
- return false;
+ return false;
}
QMimeData* BrowseTableModel::mimeData(const QModelIndexList &indexes) const {
@@ -320,7 +320,7 @@
{
Q_UNUSED(role);
- if(!index.isValid())
+ if(!index.isValid())
return false;
qDebug() << "BrowseTableModel::setData(" << index.data() << ")";
int row = index.row();
=== modified file 'mixxx/src/library/dao/cratedao.h'
--- mixxx/src/library/dao/cratedao.h 2011-10-21 00:42:23 +0000
+++ mixxx/src/library/dao/cratedao.h 2012-03-01 22:38:18 +0000
@@ -47,6 +47,8 @@
void changed(int crateId);
void trackAdded(int crateId, int trackId);
void trackRemoved(int crateId, int trackId);
+ void renamed(int crateId);
+ void lockChanged(int crateId);
private:
QSqlDatabase& m_database;
=== modified file 'mixxx/src/library/dao/playlistdao.cpp'
--- mixxx/src/library/dao/playlistdao.cpp 2011-12-18 20:23:14 +0000
+++ mixxx/src/library/dao/playlistdao.cpp 2012-03-01 22:38:18 +0000
@@ -398,7 +398,7 @@
emit(changed(playlistId));
}
-void PlaylistDAO::addToAutoDJQueue(int playlistId) {
+void PlaylistDAO::addToAutoDJQueue(int playlistId, bool bTop) {
//qDebug() << "Adding tracks from playlist " << playlistId << " to the Auto-DJ Queue";
// Query the PlaylistTracks database to locate tracks in the selected playlist
@@ -413,7 +413,15 @@
// Get the ID of the Auto-DJ playlist
int autoDJId = getPlaylistIdFromName(AUTODJ_TABLE);
// Loop through the tracks, adding them to the Auto-DJ Queue
- while(query.next()) {
- appendTrackToPlaylist(query.value(0).toInt(), autoDJId);
+
+ int i = 2; // Start at position 2 because position 1 was already loaded to the deck
+
+ while (query.next()) {
+ if (bTop) {
+ insertTrackIntoPlaylist(query.value(0).toInt(), autoDJId, i++);
+ }
+ else {
+ appendTrackToPlaylist(query.value(0).toInt(), autoDJId);
+ }
}
}
=== modified file 'mixxx/src/library/dao/playlistdao.h'
--- mixxx/src/library/dao/playlistdao.h 2011-10-21 00:42:23 +0000
+++ mixxx/src/library/dao/playlistdao.h 2012-03-01 22:38:18 +0000
@@ -53,13 +53,15 @@
/** Insert a track into a specific position in a playlist */
void insertTrackIntoPlaylist(int trackId, int playlistId, int position);
/** Add a playlist to the Auto-DJ Queue */
- void addToAutoDJQueue(int playlistId);
+ void addToAutoDJQueue(int playlistId, bool bTop);
signals:
void added(int playlistId);
void deleted(int playlistId);
void changed(int playlistId);
void trackAdded(int playlistId, int trackId, int position);
void trackRemoved(int playlistId, int trackId, int position);
+ void renamed(int playlistId);
+ void lockChanged(int playlistId);
private:
QSqlDatabase& m_database;
DISALLOW_COPY_AND_ASSIGN(PlaylistDAO);
=== modified file 'mixxx/src/library/playlistfeature.cpp'
--- mixxx/src/library/playlistfeature.cpp 2011-11-30 05:27:44 +0000
+++ mixxx/src/library/playlistfeature.cpp 2012-03-01 22:38:18 +0000
@@ -35,10 +35,14 @@
connect(m_pCreatePlaylistAction, SIGNAL(triggered()),
this, SLOT(slotCreatePlaylist()));
- m_pAddToAutoDJAction = new QAction(tr("Add to Auto-DJ Queue"),this);
+ m_pAddToAutoDJAction = new QAction(tr("Add to Auto-DJ bottom"),this);
connect(m_pAddToAutoDJAction, SIGNAL(triggered()),
this, SLOT(slotAddToAutoDJ()));
+ m_pAddToAutoDJTopAction = new QAction(tr("Add to Auto-DJ top 2"),this);
+ connect(m_pAddToAutoDJTopAction, SIGNAL(triggered()),
+ this, SLOT(slotAddToAutoDJTop()));
+
m_pDeletePlaylistAction = new QAction(tr("Remove"),this);
connect(m_pDeletePlaylistAction, SIGNAL(triggered()),
this, SLOT(slotDeletePlaylist()));
@@ -77,6 +81,7 @@
delete m_pDeletePlaylistAction;
delete m_pImportPlaylistAction;
delete m_pAddToAutoDJAction;
+ delete m_pAddToAutoDJTopAction;
delete m_pRenamePlaylistAction;
delete m_pLockPlaylistAction;
}
@@ -142,6 +147,7 @@
menu.addAction(m_pCreatePlaylistAction);
menu.addSeparator();
menu.addAction(m_pAddToAutoDJAction);
+ menu.addAction(m_pAddToAutoDJTopAction);
menu.addAction(m_pRenamePlaylistAction);
menu.addAction(m_pDeletePlaylistAction);
menu.addAction(m_pLockPlaylistAction);
@@ -430,7 +436,7 @@
//Nothing to do because the childmodel is not of lazy nature.
}
-void PlaylistFeature::slotExportPlaylist(){
+void PlaylistFeature::slotExportPlaylist() {
qDebug() << "Export playlist" << m_lastRightClickedIndex.data();
QString file_location = QFileDialog::getSaveFileName(
NULL,
@@ -481,12 +487,26 @@
void PlaylistFeature::slotAddToAutoDJ() {
//qDebug() << "slotAddToAutoDJ() row:" << m_lastRightClickedIndex.data();
+ addToAutoDJ(false); // Top = True
+}
+
+
+void PlaylistFeature::slotAddToAutoDJTop() {
+ //qDebug() << "slotAddToAutoDJTop() row:" << m_lastRightClickedIndex.data();
+ addToAutoDJ(true); // bTop = True
+}
+
+
+
+void PlaylistFeature::addToAutoDJ(bool bTop) {
+ //qDebug() << "slotAddToAutoDJ() row:" << m_lastRightClickedIndex.data();
if (m_lastRightClickedIndex.isValid()) {
int playlistId = m_playlistDao.getPlaylistIdFromName(
m_lastRightClickedIndex.data().toString());
if (playlistId >= 0) {
- m_playlistDao.addToAutoDJQueue(playlistId);
+ // Insert this playlist
+ m_playlistDao.addToAutoDJQueue(playlistId, bTop);
}
}
emit(featureUpdated());
=== modified file 'mixxx/src/library/playlistfeature.h'
--- mixxx/src/library/playlistfeature.h 2011-11-27 06:59:02 +0000
+++ mixxx/src/library/playlistfeature.h 2012-03-01 22:38:18 +0000
@@ -50,6 +50,7 @@
void slotCreatePlaylist();
void slotDeletePlaylist();
void slotAddToAutoDJ();
+ void slotAddToAutoDJTop();
void slotRenamePlaylist();
void slotTogglePlaylistLock();
void slotImportPlaylist();
@@ -59,6 +60,7 @@
private:
void constructChildModel();
void clearChildModel();
+ void addToAutoDJ(bool bTop);
TrackCollection* m_pTrackCollection;
PlaylistTableModel* m_pPlaylistTableModel;
@@ -67,6 +69,7 @@
QAction *m_pCreatePlaylistAction;
QAction *m_pDeletePlaylistAction;
QAction *m_pAddToAutoDJAction;
+ QAction *m_pAddToAutoDJTopAction;
QAction *m_pRenamePlaylistAction;
QAction *m_pLockPlaylistAction;
QAction *m_pImportPlaylistAction;
=== modified file 'mixxx/src/library/playlisttablemodel.cpp'
--- mixxx/src/library/playlisttablemodel.cpp 2011-12-18 20:23:14 +0000
+++ mixxx/src/library/playlisttablemodel.cpp 2012-03-01 22:38:18 +0000
@@ -94,6 +94,16 @@
return true;
}
+bool PlaylistTableModel::appendTrack(int trackId) {
+ if (trackId < 0)
+ return false;
+
+ m_playlistDao.appendTrackToPlaylist(trackId, m_iPlaylistId);
+
+ select(); //Repopulate the data model.
+ return true;
+}
+
TrackPointer PlaylistTableModel::getTrack(const QModelIndex& index) const {
//FIXME: use position instead of location for playlist tracks?
@@ -326,6 +336,7 @@
}
QItemDelegate* PlaylistTableModel::delegateForColumn(const int i) {
+ Q_UNUSED(i);
return NULL;
}
=== modified file 'mixxx/src/library/playlisttablemodel.h'
--- mixxx/src/library/playlisttablemodel.h 2011-11-30 05:27:44 +0000
+++ mixxx/src/library/playlisttablemodel.h 2012-03-01 22:38:18 +0000
@@ -30,6 +30,7 @@
virtual void removeTrack(const QModelIndex& index);
virtual void removeTracks(const QModelIndexList& indices);
virtual bool addTrack(const QModelIndex& index, QString location);
+ virtual bool appendTrack(int trackId);
virtual void moveTrack(const QModelIndex& sourceIndex, const QModelIndex& destIndex);
virtual void shuffleTracks(const QModelIndex& currentIndex);
=== modified file 'mixxx/src/widget/wtracktableview.cpp'
--- mixxx/src/widget/wtracktableview.cpp 2011-12-14 17:22:49 +0000
+++ mixxx/src/widget/wtracktableview.cpp 2012-03-01 22:38:18 +0000
@@ -82,6 +82,7 @@
delete m_pReloadMetadataAct;
delete m_pAutoDJAct;
+ delete m_pAutoDJTopAct;
delete m_pRemoveAct;
delete m_pPropertiesAct;
delete m_pMenu;
@@ -256,9 +257,12 @@
m_pPropertiesAct = new QAction(tr("Properties..."), this);
connect(m_pPropertiesAct, SIGNAL(triggered()), this, SLOT(slotShowTrackInfo()));
- m_pAutoDJAct = new QAction(tr("Add to Auto DJ Queue"),this);
+ m_pAutoDJAct = new QAction(tr("Add to Auto-DJ bottom"),this);
connect(m_pAutoDJAct, SIGNAL(triggered()), this, SLOT(slotSendToAutoDJ()));
+ m_pAutoDJTopAct = new QAction(tr("Add to Auto-DJ top 2"),this);
+ connect(m_pAutoDJTopAct, SIGNAL(triggered()), this, SLOT(slotSendToAutoDJTop()));
+
m_pReloadMetadataAct = new QAction(tr("Reload Track Metadata"), this);
connect(m_pReloadMetadataAct, SIGNAL(triggered()), this, SLOT(slotReloadTrackMetadata()));
}
@@ -356,6 +360,7 @@
if (modelHasCapabilities(TrackModel::TRACKMODELCAPS_ADDTOAUTODJ)) {
m_pMenu->addAction(m_pAutoDJAct);
+ m_pMenu->addAction(m_pAutoDJTopAct);
m_pMenu->addSeparator();
}
@@ -800,6 +805,15 @@
}
void WTrackTableView::slotSendToAutoDJ() {
+ // append to auto DJ
+ sendToAutoDJ(false); // bTop = false
+}
+
+void WTrackTableView::slotSendToAutoDJTop() {
+ sendToAutoDJ(true); // bTop = true
+}
+
+void WTrackTableView::sendToAutoDJ(bool bTop) {
if (!modelHasCapabilities(TrackModel::TRACKMODELCAPS_ADDTOAUTODJ)) {
return;
}
@@ -819,7 +833,13 @@
(pTrack = trackModel->getTrack(index))) {
int iTrackId = pTrack->getId();
if (iTrackId != -1) {
- playlistDao.appendTrackToPlaylist(iTrackId, iAutoDJPlaylistId);
+ if (bTop) {
+ // Load track to position two because position one is already loaded to the player
+ playlistDao.insertTrackIntoPlaylist(iTrackId, iAutoDJPlaylistId, 2);
+ }
+ else {
+ playlistDao.appendTrackToPlaylist(iTrackId, iAutoDJPlaylistId);
+ }
}
}
}
=== modified file 'mixxx/src/widget/wtracktableview.h'
--- mixxx/src/widget/wtracktableview.h 2011-10-14 03:58:14 +0000
+++ mixxx/src/widget/wtracktableview.h 2012-03-01 22:38:18 +0000
@@ -46,6 +46,7 @@
void slotNextTrackInfo();
void slotPrevTrackInfo();
void slotSendToAutoDJ();
+ void slotSendToAutoDJTop();
void slotReloadTrackMetadata();
void addSelectionToPlaylist(int iPlaylistId);
void addSelectionToCrate(int iCrateId);
@@ -53,6 +54,7 @@
void doSortByColumn(int headerSection);
private:
+ void sendToAutoDJ(bool bTop);
void showTrackInfo(QModelIndex index);
void createActions();
void dragMoveEvent(QDragMoveEvent * event);
@@ -89,6 +91,7 @@
// Send to Auto-DJ Action
QAction *m_pAutoDJAct;
+ QAction *m_pAutoDJTopAct;
// Remove from table
QAction *m_pRemoveAct;