Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Livemetadata PR #1675

Closed
wants to merge 79 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
32cece7
Added .vscode on gitignore
davidhm May 5, 2018
ba829a2
First few files
davidhm May 14, 2018
5169748
So far manual tests are working
davidhm May 16, 2018
3d8c501
Pre automatic tests
davidhm May 18, 2018
523d09b
Using github as a backup
davidhm May 18, 2018
23ef862
Error when compiling moc generated cpp
davidhm May 20, 2018
0a4a4d6
WIP: Automatic tests
davidhm May 23, 2018
d203e85
Moved timers away from Track object
davidhm May 24, 2018
1a6bc0d
Pre volume scrobbling
davidhm May 26, 2018
ff27795
Pre tests, scrobbling manager
davidhm May 27, 2018
db2db23
Deadlock
davidhm May 30, 2018
7f55150
Solved the deadlock, simple tests pass
davidhm Jun 1, 2018
121443e
WIP: Adding file listener
davidhm Jun 2, 2018
2cd5bbc
Fixed file buffer, it's automatically updated now
davidhm Jun 3, 2018
b9c4a6c
[Untested] Fixed file info, modified metadatabroadcast
davidhm Jun 5, 2018
e10df9e
[WIP] Adding tests for scrobbling manager
davidhm Jun 7, 2018
c1de7db
Added first test for scrobbling manager
davidhm Jun 9, 2018
50019b0
File listener template + factory
davidhm Jun 10, 2018
d805306
Scrobbling tests done
davidhm Jun 12, 2018
4e714d5
[WIP] Adding file preferences
davidhm Jun 12, 2018
b3f8ea8
Preferences mock-up
davidhm Jun 13, 2018
8cd9c16
Changed everything to a weak pointer
davidhm Jun 13, 2018
d4b9aa5
Added file listener path in options
davidhm Jun 14, 2018
ec98ef6
[WIP] Persistent config now playing file
davidhm Jun 14, 2018
0209b4a
[WIP] Requested changes
davidhm Jun 15, 2018
2d8f4a2
Adding new tab
davidhm Jun 17, 2018
88c4819
Added mock-up in preferences
davidhm Jun 17, 2018
ab8b524
Table view mockup
davidhm Jun 18, 2018
97daf77
Pre changing prefmetadata class
davidhm Jun 19, 2018
4bc2de3
Added file settings
davidhm Jun 20, 2018
49b8b93
[Untested] Added options to file listener
davidhm Jun 20, 2018
567e9b5
Modified settings, added concurrency
davidhm Jun 23, 2018
5748fa9
Added dedicated thread
davidhm Jun 26, 2018
3a677b6
Modified author and title string
davidhm Jun 26, 2018
9c43d09
Merge branch 'master' into Livemetadata
davidhm Jun 26, 2018
2c21183
Added connections to lambda expressions in player manager, file liste…
davidhm Jun 28, 2018
a6d67d7
Fixed tests failing
davidhm Jun 29, 2018
ba8a6fc
Added mock network manager, gotta test with mock server
davidhm Jul 1, 2018
6b7f207
Now listening scrobbles work with ListenBrainz
davidhm Jul 5, 2018
f7c6a83
Deleted log file
davidhm Jul 5, 2018
1057b06
Merge branch 'master' into Livemetadata
davidhm Jul 6, 2018
152925c
ListenBrainz full scrobbles work now too
davidhm Jul 6, 2018
ad43628
Fixed double delete in developer mode
davidhm Jul 7, 2018
751f567
Forgot to compile
davidhm Jul 7, 2018
64d35c5
Modified metadata file options
davidhm Jul 7, 2018
ddfb859
Editable combobox
davidhm Jul 9, 2018
e4dc8df
Added mpris stub, not working
davidhm Jul 11, 2018
a1ad4c6
MPRIS now reflects the playback state
davidhm Jul 12, 2018
ee4c5a5
Disabled failing test until a solution is found
davidhm Jul 13, 2018
4571d43
Fixed broken tests, continuing MPRIS implementation
davidhm Jul 18, 2018
185d2f2
Fixed non compiling build
davidhm Jul 18, 2018
0bc22be
Segfault on weak_ptr
davidhm Jul 19, 2018
0af2279
Fixed eject bug
davidhm Jul 19, 2018
6be0042
Mpris reflects AutoDJ enabled
davidhm Jul 19, 2018
62eae49
Pause, play and go next MPRIS functions work
davidhm Jul 21, 2018
c2317c7
Fixed correct fade-in in MPRIS
davidhm Jul 22, 2018
8b5e54a
Added volume, playback status and loop status as well as a LINUX define
davidhm Jul 23, 2018
cac8c1f
Moved MPRIS into a feature
davidhm Jul 24, 2018
6807838
Added MPRIS macro in includes too
davidhm Jul 24, 2018
d6880a1
MPRIS is seekable now
davidhm Jul 24, 2018
32e565a
MPRIS broadcasts current track and rate works now too
davidhm Jul 25, 2018
1b77c8b
Modified linked lists into hash maps
davidhm Aug 1, 2018
7ba10a7
Added space after commas
davidhm Aug 1, 2018
94ab525
Changed ref ampersand and disabled non working test
davidhm Aug 1, 2018
5e8fb60
Added more button in encoding combo box
davidhm Aug 3, 2018
41bdfb9
Resized combobox
davidhm Aug 6, 2018
0def3e3
Merge remote-tracking branch 'upstream/master' into Livemetadata
davidhm Aug 6, 2018
9fe5277
Added few UI suggestions
davidhm Aug 6, 2018
97271d8
Missing include
davidhm Aug 7, 2018
f4b9649
Added cover art to mpris
davidhm Aug 11, 2018
dde6c47
Added cover art to MPRIS player
davidhm Aug 12, 2018
e1cfd7a
Fixed few things
davidhm Aug 14, 2018
69a3020
Deleting all cover art files
davidhm Aug 17, 2018
7af4dd7
Single file image
davidhm Aug 17, 2018
170e6c9
Cover art file is now QTemporaryFile
davidhm Aug 18, 2018
8c6fa58
Revamped encoding combobox
davidhm Aug 18, 2018
899f207
Fixed some cover URL generation issues
daschuer Aug 19, 2018
4a13665
Small fixes
davidhm Aug 20, 2018
39dc901
Merge pull request #1 from daschuer/Livemetadata
davidhm Aug 20, 2018
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,5 @@ lib/*/*.lib
lib/*/lib/*.lib

lib/qtscript-bytearray/*.cc

*.vscode
Copy link
Member

@Holzhaus Holzhaus Aug 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is not created by Mixxx or its build system. Adding patterns for every conceivable editor/IDE to this project's gitignore is neither desirable nor feasible. You should add it to your global gitignore instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, we should stop adding these editor generated files to our shared .gitignore and remove the ones that are already there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was already mentioned in that PR ages ago. I can't seem to find it.

3 changes: 3 additions & 0 deletions build/depends.py
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,8 @@ def sources(self, build):
"control/controlttrotary.cpp",
"control/controlencoder.cpp",

"broadcast/metadatabroadcast.cpp",

"controllers/dlgcontrollerlearning.cpp",
"controllers/dlgprefcontroller.cpp",
"controllers/dlgprefcontrollers.cpp",
Expand Down Expand Up @@ -1093,6 +1095,7 @@ def sources(self, build):
"track/trackinfo.cpp",
"track/trackrecord.cpp",
"track/trackref.cpp",
"track/trackplaytimers.cpp",

"mixer/auxiliary.cpp",
"mixer/baseplayer.cpp",
Expand Down
37 changes: 37 additions & 0 deletions src/broadcast/metadatabroadcast.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "metadatabroadcast.h"
#include "mixer/playerinfo.h"

MetadataBroadcast::MetadataBroadcast() {
/*connect(&PlayerInfo::instance(),SIGNAL(trackLoaded(QString,TrackPointer)),
this,SLOT(slotTrackLoaded(QString,TrackPointer)));
connect(&PlayerInfo::instance(),SIGNAL(trackUnloaded(QString,TrackPointer)),
this,SLOT(slotTrackUnloaded(QString,TrackPointer)));
connect(&PlayerInfo::instance(),SIGNAL(trackPaused(QString,TrackPointer)),
this,SLOT(slotTrackPaused(QString,TrackPointer)));
connect(&PlayerInfo::instance(),SIGNAL(trackResumed(QString,TrackPointer)),
this,SLOT(slotTrackResumed(QString,TrackPointer)));*/
}

void MetadataBroadcast::slotTrackLoaded(QString group, TrackPointer pTrack) {
if (!pTrack)
return;
qDebug() << "Track " << pTrack->getTitle() << "loaded in group " << group << ".";
}

void MetadataBroadcast::slotTrackUnloaded(QString group, TrackPointer pTrack) {
if (!pTrack)
return;
qDebug() << "Track " << pTrack->getTitle() << "unloaded in group " << group << ".";
}

void MetadataBroadcast::slotTrackPaused(QString group, TrackPointer pTrack) {
if (!pTrack)
return;
qDebug() << "Track " << pTrack->getTitle() << "paused in group " << group << ".";
}

void MetadataBroadcast::slotTrackResumed(QString group, TrackPointer pTrack) {
if (!pTrack)
return;
qDebug() << "Track " << pTrack->getTitle() << "resumed in group " << group << ".";
}
13 changes: 13 additions & 0 deletions src/broadcast/metadatabroadcast.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <QObject>
#include "track/track.h"

class MetadataBroadcast : public QObject {
Q_OBJECT
public:
MetadataBroadcast();
public slots:
void slotTrackLoaded(QString group, TrackPointer pTrack);
void slotTrackUnloaded(QString group, TrackPointer pTrack);
void slotTrackPaused(QString group, TrackPointer pTrack);
void slotTrackResumed(QString group, TrackPointer pTrack);
};
8 changes: 8 additions & 0 deletions src/mixer/basetrackplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,10 @@ void BaseTrackPlayerImpl::slotSetReplayGain(mixxx::ReplayGain replayGain) {
}

void BaseTrackPlayerImpl::slotPlayToggled(double v) {
if (v == 0)
emit(trackPaused(m_pLoadedTrack));
else if (v == 1)
emit(trackResumed(m_pLoadedTrack));
if (!v && m_replaygainPending) {
setReplayGain(m_pLoadedTrack->getReplayGain().getRatio());
}
Expand Down Expand Up @@ -472,3 +476,7 @@ void BaseTrackPlayerImpl::setReplayGain(double value) {
m_pReplayGain->set(value);
m_replaygainPending = false;
}

bool BaseTrackPlayerImpl::isTrackPaused() const {
return m_pPlay->toBool();
}
4 changes: 4 additions & 0 deletions src/mixer/basetrackplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class BaseTrackPlayer : public BasePlayer {
void playerEmpty();
void noPassthroughInputConfigured();
void noVinylControlInputConfigured();
void trackPaused(TrackPointer pPausedTrack);
void trackResumed(TrackPointer pResumedTrack);
};

class BaseTrackPlayerImpl : public BaseTrackPlayer {
Expand All @@ -70,6 +72,8 @@ class BaseTrackPlayerImpl : public BaseTrackPlayer {
// For testing, loads a fake track.
TrackPointer loadFakeTrack(bool bPlay, double filebpm);

bool isTrackPaused() const;

public slots:
void slotLoadTrack(TrackPointer track, bool bPlay) final;
void slotTrackLoaded(TrackPointer pNewTrack, TrackPointer pOldTrack);
Expand Down
74 changes: 73 additions & 1 deletion src/mixer/playermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "util/assert.h"
#include "util/stat.h"
#include "util/sleepableqthread.h"
#include "broadcast/metadatabroadcast.h"

//static
QAtomicPointer<ControlProxy> PlayerManager::m_pCOPNumDecks;
Expand Down Expand Up @@ -51,7 +52,9 @@ PlayerManager::PlayerManager(UserSettingsPointer pConfig,
m_pCONumMicrophones(new ControlObject(
ConfigKey("[Master]", "num_microphones"), true, true)),
m_pCONumAuxiliaries(new ControlObject(
ConfigKey("[Master]", "num_auxiliaries"), true, true)) {
ConfigKey("[Master]", "num_auxiliaries"), true, true)),
m_pMetadataBroadcast(new MetadataBroadcast())
{
connect(m_pCONumDecks, SIGNAL(valueChanged(double)),
this, SLOT(slotNumDecksControlChanged(double)),
Qt::DirectConnection);
Expand Down Expand Up @@ -109,6 +112,7 @@ PlayerManager::~PlayerManager() {
delete m_pCONumPreviewDecks;
delete m_pCONumMicrophones;
delete m_pCONumAuxiliaries;
delete m_pMetadataBroadcast;
if (m_pAnalyzerQueue) {
delete m_pAnalyzerQueue;
}
Expand Down Expand Up @@ -366,6 +370,17 @@ void PlayerManager::addDeckInner() {
connect(pDeck, SIGNAL(noVinylControlInputConfigured()),
this, SIGNAL(noVinylControlInputConfigured()));

connect(pDeck,SIGNAL(trackPaused(TrackPointer)),
this, SLOT(slotTrackPaused(TrackPointer)));
connect(pDeck,SIGNAL(trackResumed(TrackPointer)),
this, SLOT(slotTrackResumed(TrackPointer)));
connect(pDeck,SIGNAL(newTrackLoaded(TrackPointer)),
this, SLOT(slotNewTrackLoaded(TrackPointer)));
connect(pDeck,SIGNAL(loadingTrack(TrackPointer,TrackPointer)),
this, SLOT(slotLoadingTrack(TrackPointer,TrackPointer)));
connect(pDeck,SIGNAL(playerEmpty()),
this, SLOT(slotPlayerEmpty()));

if (m_pAnalyzerQueue) {
connect(pDeck, SIGNAL(newTrackLoaded(TrackPointer)),
m_pAnalyzerQueue, SLOT(slotAnalyseTrack(TrackPointer)));
Expand Down Expand Up @@ -620,3 +635,60 @@ void PlayerManager::slotLoadTrackIntoNextAvailableSampler(TrackPointer pTrack) {
++it;
}
}

void PlayerManager::slotTrackPaused(TrackPointer pPausedTrack) {
if (!pPausedTrack)
return;
QMutexLocker locker(&m_mutex);
bool allPaused = true;
foreach (Deck *deck,m_decks) {
if (deck->getLoadedTrack() == pPausedTrack && !deck->isTrackPaused()) {
allPaused = false;
break;
}
}
if (allPaused)
pPausedTrack->pausePlayedTime();
}

void PlayerManager::slotTrackResumed(TrackPointer pPausedTrack) {
if (!pPausedTrack)
return;
QMutexLocker locker(&m_mutex);
pPausedTrack->resumePlayedTime();
}

void PlayerManager::slotLoadingTrack(TrackPointer pNewTrack, TrackPointer pOldTrack) {
QMutexLocker locker(&m_mutex);
Deck *loadingDeck = qobject_cast<Deck*>(sender());
if (pOldTrack) {
bool allUnloaded = true;
foreach(Deck *deck,m_decks) {
if (deck != loadingDeck && deck->getLoadedTrack() == pOldTrack) {
allUnloaded = false;
break;
}
}
if (allUnloaded)
m_tracksToBeReset.append(trackDeckPair(pOldTrack,loadingDeck));
}
}

void PlayerManager::slotNewTrackLoaded(TrackPointer pNewTrack) {
resetTrack(qobject_cast<Deck*>(sender()));
}

void PlayerManager::slotPlayerEmpty() {
resetTrack(qobject_cast<Deck*>(sender()));
}

void PlayerManager::resetTrack(Deck *deck) {
QMutexLocker locker(&m_mutex);
Deck *loadingDeck = qobject_cast<Deck*>(sender());
foreach (trackDeckPair pair,m_tracksToBeReset) {
if (loadingDeck == pair.pDeck) {
pair.pTrack->resetPlayedTime();
break;
}
}
}
24 changes: 23 additions & 1 deletion src/mixer/playermanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class PreviewDeck;
class Sampler;
class SamplerBank;
class SoundManager;
class MetadataBroadcast;

// For mocking PlayerManager.
class PlayerManagerInterface {
Expand Down Expand Up @@ -233,10 +234,21 @@ class PlayerManager : public QObject, public PlayerManagerInterface {
// Must hold m_mutex before calling this method. Internal method that
// creates a new auxiliary.
void addAuxiliaryInner();
//Resets the played timer in the track a just switched.
void resetTrack(Deck *deck);

// Used to protect access to PlayerManager state across threads.
mutable QMutex m_mutex;

private slots:
void slotTrackPaused(TrackPointer pPausedTrack);
void slotTrackResumed(TrackPointer pResumedTrack);
void slotLoadingTrack(TrackPointer pNewTrack, TrackPointer pOldTrack);
void slotNewTrackLoaded(TrackPointer pNewTrack);
void slotPlayerEmpty();

private:

UserSettingsPointer m_pConfig;
SoundManager* m_pSoundManager;
EffectsManager* m_pEffectsManager;
Expand All @@ -254,7 +266,17 @@ class PlayerManager : public QObject, public PlayerManagerInterface {
QList<PreviewDeck*> m_preview_decks;
QList<Microphone*> m_microphones;
QList<Auxiliary*> m_auxiliaries;
QMap<QString, BaseTrackPlayer*> m_players;
QMap<QString, BaseTrackPlayer*> m_players;

//Live metadata section
MetadataBroadcast *m_pMetadataBroadcast;
struct trackDeckPair {
TrackPointer pTrack;
Deck *pDeck;
trackDeckPair(TrackPointer pTrack, Deck *pDeck) :
pTrack(pTrack),pDeck(pDeck) {}
};
QList<trackDeckPair> m_tracksToBeReset;
};

#endif // MIXER_PLAYERMANAGER_H
46 changes: 46 additions & 0 deletions src/test/trackplayedtimer_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "track/track.h"
#include "track/trackplaytimers.h"
#include "test/trackplayedtimer_test.h"

class ElapsedTimerMock : public TrackTimers::ElapsedTimer {
public:
~ElapsedTimerMock() = default;
MOCK_METHOD0(invalidate,void());
MOCK_METHOD0(start,void());
MOCK_METHOD0(isValid,bool());
MOCK_METHOD0(elapsed,qint64());
};


class TrackTest : public testing::Test {
public:
TrackTest() {
testTrack = Track::newDummy(QFileInfo(),TrackId());
}
~TrackTest() = default;
TrackPointer testTrack;
public slots:
};

TEST_F(TrackTest,SendsSignalWhenScrobbable) {
testTrack->setDuration(5);
ElapsedTimerMock etmock;
TimerMock tmock;
EXPECT_CALL(etmock,invalidate());
EXPECT_CALL(etmock,isValid())
.WillOnce(testing::Return(false))
.WillOnce(testing::Return(true));
EXPECT_CALL(etmock,start());
EXPECT_CALL(tmock,start(1000))
.WillOnce(testing::InvokeWithoutArgs(testTrack.get(),
&Track::slotCheckIfScrobbable));
EXPECT_CALL(etmock,elapsed())
.WillOnce(testing::Return(2500));
testTrack->setTimer(&tmock);
testTrack->setElapsedTimer(&etmock);
testTrack->resetPlayedTime();
testTrack->resumePlayedTime();
ASSERT_TRUE(testTrack->isScrobbable());
}
12 changes: 12 additions & 0 deletions src/test/trackplayedtimer_test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <QObject>
#include "track/trackplaytimers.h"
#include "gmock/gmock.h"

class TimerMock : public TrackTimers::TrackTimer {
Q_OBJECT
public:
~TimerMock() = default;
MOCK_METHOD1(start,void(int msec));
MOCK_METHOD0(isActive,bool());
MOCK_METHOD0(stop,void());
};
Loading