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

Auto dj crates #18

Merged
merged 29 commits into from
Jul 16, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
eb6d41b
First version of auto-DJ crates.
ulatekh May 4, 2013
638c8b7
Just some minor changes to comments.
ulatekh May 10, 2013
de8a563
Merged with trunk; minor updates to merge conflicting changes.
ulatekh May 10, 2013
6a30eb3
Now the auto-DJ-crates table stores the last time the track was playe…
ulatekh May 12, 2013
ab9046c
Merged with lp:mixxx
ulatekh May 16, 2013
43360c9
Made the auto-DJ-crates feature subject to conditional compilation.
ulatekh May 16, 2013
417532a
Implemented an "Add crate" menu on the "Crates" tree-item in the "Aut…
ulatekh May 16, 2013
6e4f2f0
Changed "Add Crate to AutoDJ" to "Connect to AutoDJ", and "Remove Cra…
ulatekh Jun 3, 2013
02bd977
One more menu item needed updating -- "Add crate" is now "Connect Cra…
ulatekh Jun 3, 2013
dea693d
Merged with lp:mixxx
ulatekh Jun 5, 2013
f1a6d70
Now random-tracks chosen by the auto-DJ-crates feature can be in term…
ulatekh Jun 5, 2013
9d34467
Now auto-DJ-crates better handles situations where very few tracks ar…
ulatekh Jun 6, 2013
1ed581f
One more change to low-track situations in auto-DJ-crates.
ulatekh Jun 7, 2013
72cad18
Merged with lp:mixxx
ulatekh Jun 9, 2013
8e03aa0
Merge branch 'master' into auto-dj-crates
daschuer Jun 20, 2013
4a9ffe7
Merge branch 'master' of https://github.com/mixxxdj/mixxx into auto-d…
ulatekh Jun 22, 2013
60de69f
Fixed lots of formatting issues.
ulatekh Jun 22, 2013
1bc835b
Because early returns are completely different than gotos, and _so_ m…
ulatekh Jun 23, 2013
5f63af5
Merge pull request #1 from ulatekh/auto-dj-crates
daschuer Jun 24, 2013
d9c096a
allow not adding a track if no condition fits
daschuer Jun 24, 2013
8df76eb
unified wording, added tooltip for checkbox
daschuer Jun 24, 2013
6735fbc
Merge branch 'master' into autodj-crates2
daschuer Jul 7, 2013
d7cf2c1
Merge branch 'master' into auto-dj-crates
daschuer Jul 15, 2013
b3743ef
Fixed issues from RJs comments; Made crates menu "Auto DJ Source"
daschuer Jul 15, 2013
0d7af53
Changed context menu for crates in AutoDj tree
daschuer Jul 15, 2013
41d1168
fixed auto dj crate tree population after restart
daschuer Jul 16, 2013
852546d
Fixed Dynamic deck count in auto dj crates. Removed use of QMap::[] in
daschuer Jul 16, 2013
92bddf1
Tweaked GUI strings for auto dj crates
daschuer Jul 16, 2013
1c3df49
Merge branch 'master' into auto-dj-crates
daschuer Jul 16, 2013
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
1 change: 1 addition & 0 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ available_features = [features.HifiEq,
features.MSVSHacks,
features.Vamp,
features.PromoTracks,
features.AutoDjCrates,

# "Features" of dubious quality
features.PerfTools,
Expand Down
24 changes: 23 additions & 1 deletion build/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def sources(self, build):
sources = ['controllers/bulk/bulkcontroller.cpp',
'controllers/bulk/bulkenumerator.cpp']
if not int(build.flags['hid']):
sources.append('controllers/hid/hidcontrollerpresetfilehandler.cpp')
sources.append('controllers/hid/hidcontrollerpresetfilehandler.cpp')
return sources


Expand Down Expand Up @@ -1082,3 +1082,25 @@ def sources(self, build):
'library/bundledsongswebview.cpp',
"library/featuredartistswebview.cpp",
]

class AutoDjCrates(Feature):
def description(self):
return "Auto-DJ crates (for random tracks)"

def enabled(self, build):
build.flags['autodjcrates'] = \
util.get_flags(build.env, 'autodjcrates', 1)
if int(build.flags['autodjcrates']):
return True
return False

def add_options(self, build, vars):
vars.Add('autodjcrates', 'Set to 1 to enable crates as a source for random Auto-DJ tracks.', 1)

def configure(self, build, conf):
if not self.enabled(build):
return
build.env.Append(CPPDEFINES = '__AUTODJCRATES__')

def sources(self, build):
return ['library/dao/autodjcratesdao.cpp']
28 changes: 18 additions & 10 deletions build/qtcreator/mixxx.pro
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CONFIG += debug link_pkgconfig portmidi script vinylcontrol m4a
CONFIG += debug link_pkgconfig portmidi script vinylcontrol m4a autodjcrates
# ladspa
DEFINES += QMAKE \ # define QMAKE for not-SCons specific ifdefs like ui_scriptstudio.h
__PORTAUDIO__ \
Expand Down Expand Up @@ -742,15 +742,15 @@ SOURCES += $$BASE_DIR/src/vamp/vampanalyser.cpp \
$$BASE_DIR/src/analyservamptest.cpp \
$$BASE_DIR/src/analyservampkeytest.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/PluginBufferingAdapter.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/PluginChannelAdapter.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/PluginHostAdapter.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/PluginInputDomainAdapter.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/PluginLoader.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/PluginSummarisingAdapter.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/PluginWrapper.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/RealTime.cpp \
$$BASE_DIR/lib/vamp/src/vamp-sdk/PluginAdapter.cpp \
$$BASE_DIR/lib/vamp/src/vamp-sdk/RealTime.cpp
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/PluginChannelAdapter.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/PluginHostAdapter.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/PluginInputDomainAdapter.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/PluginLoader.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/PluginSummarisingAdapter.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/PluginWrapper.cpp \
$$BASE_DIR/lib/vamp/src/vamp-hostsdk/RealTime.cpp \
$$BASE_DIR/lib/vamp/src/vamp-sdk/PluginAdapter.cpp \
$$BASE_DIR/lib/vamp/src/vamp-sdk/RealTime.cpp
}

CONFIG(tonal) {
Expand Down Expand Up @@ -856,6 +856,14 @@ CONFIG(ffmpeg) {
-logg
}

CONFIG(autodjcrates) {
DEFINES += __AUTODJCRATES__
HEADERS +=
$$BASE_DIR/src/library/dao/autodjcratesdao.h
SOURCES +=
$$BASE_DIR/src/library/dao/autodjcratesdao.cpp
}

# Copy Windows dependencies to DESTDIR.
win32 {
!exists($$DESTDIR):system( mkdir \"$$replace(DESTDIR, /,$$DIR_SEPARATOR)\" )
Expand Down
14 changes: 14 additions & 0 deletions src/dlgautodj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ DlgAutoDJ::DlgAutoDJ(QWidget* parent, ConfigObject<ConfigValue>* pConfig,
connect(pushButtonSkipNext, SIGNAL(clicked(bool)),
this, SLOT(skipNextButton(bool)));

#ifdef __AUTODJCRATES__
connect(pushButtonAddRandom, SIGNAL(clicked(bool)),
this, SIGNAL(addRandomButton(bool)));
#else // __AUTODJCRATES__
pushButtonAddRandom->setVisible(false);
horizontalLayout->removeWidget(pushButtonAddRandom);
#endif // __AUTODJCRATES__

m_pCOFadeNow = new ControlPushButton(
ConfigKey("[AutoDJ]", "fade_now"));
m_pCOTFadeNow = new ControlObjectThreadMain(m_pCOFadeNow->getKey());
Expand Down Expand Up @@ -666,3 +674,9 @@ void DlgAutoDJ::transitionValueChanged(int value) {
ConfigValue(value));
m_backUpTransition = value;
}

void DlgAutoDJ::enableRandomButton(bool enabled) {
#ifdef __AUTODJCRATES__
pushButtonAddRandom->setEnabled(enabled);
#endif // __AUTODJCRATES__
}
2 changes: 2 additions & 0 deletions src/dlgautodj.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ class DlgAutoDJ : public QWidget, public Ui::DlgAutoDJ, public LibraryView {
void player1PlayChanged(double value);
void player2PlayChanged(double value);
void transitionValueChanged(int value);
void enableRandomButton(bool enabled);

signals:
void addRandomButton(bool buttonChecked);
void loadTrack(TrackPointer tio);
void loadTrackToPlayer(TrackPointer tio, QString group, bool);

Expand Down
7 changes: 7 additions & 0 deletions src/dlgautodj.ui
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonAddRandom">
<property name="text">
<string>Add random</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonSkipNext">
<property name="toolTip">
Expand Down
66 changes: 64 additions & 2 deletions src/dlgprefcontrols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,45 @@ DlgPrefControls::DlgPrefControls(QWidget * parent, MixxxApp * mixxx,
ComboBoxAutoDjRequeue->setCurrentIndex(m_pConfig->getValueString(ConfigKey("[Auto DJ]", "Requeue")).toInt());
connect(ComboBoxAutoDjRequeue, SIGNAL(activated(int)), this, SLOT(slotSetAutoDjRequeue(int)));

#ifdef __AUTODJCRATES__

// The minimum available for randomly-selected tracks
autoDjMinimumAvailableSpinBox->setValue(
m_pConfig->getValueString(
ConfigKey("[Auto DJ]", "MinimumAvailable"), "20").toInt());
connect(autoDjMinimumAvailableSpinBox, SIGNAL(valueChanged(int)), this,
SLOT(slotSetAutoDjMinimumAvailable(int)));

// The auto-DJ replay-age for randomly-selected tracks
autoDjIgnoreTimeCheckBox->setChecked(
(bool) m_pConfig->getValueString(
ConfigKey("[Auto DJ]", "UseIgnoreTime"), "0").toInt());
connect(autoDjIgnoreTimeCheckBox, SIGNAL(stateChanged(int)), this,
SLOT(slotSetAutoDjUseIgnoreTime(int)));
autoDjIgnoreTimeEdit->setTime(
QTime::fromString(
m_pConfig->getValueString(
ConfigKey("[Auto DJ]", "IgnoreTime"), "23:59"),
autoDjIgnoreTimeEdit->displayFormat()));
autoDjIgnoreTimeEdit->setEnabled(
autoDjIgnoreTimeCheckBox->checkState() == Qt::Checked);
connect(autoDjIgnoreTimeEdit, SIGNAL(timeChanged(const QTime &)), this,
SLOT(slotSetAutoDjIgnoreTime(const QTime &)));

#else // __AUTODJCRATES__

// Remove the preferences.
autoDjMinimumAvailableLabel->setVisible(false);
GridLayout1->removeWidget(autoDjMinimumAvailableLabel);
autoDjMinimumAvailableSpinBox->setVisible(false);
GridLayout1->removeWidget(autoDjMinimumAvailableSpinBox);
autoDjIgnoreTimeCheckBox->setVisible(false);
GridLayout1->removeWidget(autoDjIgnoreTimeCheckBox);
autoDjIgnoreTimeEdit->setVisible(false);
GridLayout1->removeWidget(autoDjIgnoreTimeEdit);

#endif // __AUTODJCRATES__

//
// Skin configurations
//
Expand Down Expand Up @@ -424,8 +463,31 @@ void DlgPrefControls::slotSetAutoDjRequeue(int)
m_pConfig->set(ConfigKey("[Auto DJ]", "Requeue"), ConfigValue(ComboBoxAutoDjRequeue->currentIndex()));
}

void DlgPrefControls::slotSetTooltips(int)
{
void DlgPrefControls::slotSetAutoDjMinimumAvailable(int a_iValue) {
#ifdef __AUTODJCRATES__
QString str;
str.setNum(a_iValue);
Copy link
Member

Choose a reason for hiding this comment

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

QString::number() would work better here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, it works exactly the same. Your issue is purely stylistic.

Copy link
Member

Choose a reason for hiding this comment

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

Yep -- could you change it please?

Copy link
Contributor

Choose a reason for hiding this comment

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

I can't believe this multitude of minor style issues are enough to hold up merging these changes.
Your focus on style over substance is hard to understand.

Copy link
Member

Choose a reason for hiding this comment

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

(It's something I would change myself once your branch is merged as part of cleanup that I do whenever a branch merges. Now that we have GitHub line-by-line commenting I get to ask you to do it instead of me!)

Copy link
Member

Choose a reason for hiding this comment

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

@ulatekh Coding style, especially in a language like C++, is wide open to interpretation and variation. We could use camelCase, lpHungarianNotation, or some_other_style_. If every developer used whatever style they wanted, the code would be harder to read because it wouldn't be consistent from module to module. In fact, mixxx already has major problems because of this (the vinylcontrol code, which I'm in charge of, comes to mind :/).

Therefore, style is actually a pretty important part of our review process, and we're actually a lot more lax than other organizations. We don't enforce column limits, we allow lone braces on following lines, etc -- even though it might help readability to be more strict. The old adage applies: code is read more often than written. As a project that is starting to get quite large and with a large developer community, having a core style is becoming more important. So while it's absolutely true that RJ's suggestions are functionally equivalent to what you wrote, there are two more important things to keep in mind: 1) RJ is not criticizing your ability or opinions directly -- there's nothing personal involved; and 2) RJ knows how most of the code looks in mixxx and knows what we other developers are used to seeing. I know it's difficult to slog through a ton of comments that seem nit-picky, but the result will be more consistent code for everyone to read.

I understand that you might prefer certain patterns, and goodness knows there are some patterns I'm asked to write in my paying work that I don't agree with, but we have good reasons for asking for the style changes we ask for and we hope that you can give us the benefit of the doubt and roll with the nitpicks. If you feel like we're removing some evidence of your personality from your code, that's not entirely false -- we'd like all of the code to feel like Mixxx code, regardless of which developer wrote it. But the upside is that the codebase feels more cohesive and is easier for others to learn.

m_pConfig->set(ConfigKey("[Auto DJ]","MinimumAvailable"),str);
#endif // __AUTODJCRATES__
}

void DlgPrefControls::slotSetAutoDjUseIgnoreTime(int a_iState) {
#ifdef __AUTODJCRATES__
bool bChecked = (a_iState == Qt::Checked);
QString strChecked = (bChecked) ? "1" : "0";
m_pConfig->set(ConfigKey("[Auto DJ]", "UseIgnoreTime"), strChecked);
autoDjIgnoreTimeEdit->setEnabled(bChecked);
#endif // __AUTODJCRATES__
}

void DlgPrefControls::slotSetAutoDjIgnoreTime(const QTime &a_rTime) {
#ifdef __AUTODJCRATES__
QString str = a_rTime.toString(autoDjIgnoreTimeEdit->displayFormat());
m_pConfig->set(ConfigKey("[Auto DJ]", "IgnoreTime"),str);
#endif // __AUTODJCRATES__
}

void DlgPrefControls::slotSetTooltips(int) {
int configValue = (ComboBoxTooltips->currentIndex() + 1) % 3;
m_mixxx->setToolTipsCfg(configValue);
}
Expand Down
3 changes: 3 additions & 0 deletions src/dlgprefcontrols.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ public slots:
void slotSetCueDefault(int);
void slotSetCueRecall(int);
void slotSetAutoDjRequeue(int);
void slotSetAutoDjMinimumAvailable(int);
void slotSetAutoDjUseIgnoreTime(int);
void slotSetAutoDjIgnoreTime(const QTime &a_rTime);
void slotSetRateRamp(bool);
void slotSetRateRampSensitivity(int);
void slotSetLocale(int);
Expand Down
45 changes: 44 additions & 1 deletion src/dlgprefcontrolsdlg.ui
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
Copy link
Member

Choose a reason for hiding this comment

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

I think this ought to go in a new preferences section for AutoDJ. That will pave the way for more advanced AutoDJ stuff.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, of cause. But the preferences reordering is out of scope of this project. So this could be done after merging the advanced-auto-dj branch as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you, Daniel. I appreciate your reasonableness.

Copy link
Member

Choose a reason for hiding this comment

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

We treat this dialog like a clown car. AutoDJ requeue shouldn't have gone in here in the first place. Doing this with the advanced autodj work sounds good -- thanks Daniel.

Copy link
Contributor

Choose a reason for hiding this comment

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

I put them here because the "Interface" preferences already had the "re-queue tracks in Auto DJ" entry.

Copy link
Member

Choose a reason for hiding this comment

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

No need to explain -- that's reasonable. There's a tipping point and we're pretty much at it is all I'm saying.

<y>0</y>
<width>519</width>
<height>729</height>
<height>939</height>
</rect>
</property>
<property name="windowTitle">
Expand Down Expand Up @@ -283,6 +283,49 @@
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="autoDjMinimumAvailableLabel">
<property name="text">
<string>Auto DJ: Minimum available tracks [%]</string>
</property>
</widget>
</item>
<item row="11" column="1" colspan="2">
<widget class="QSpinBox" name="autoDjMinimumAvailableSpinBox">
<property name="toolTip">
<string>This percentage of tracks are always available for selecting, regardless of when they were last played.</string>
Copy link
Member

Choose a reason for hiding this comment

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

It's pretty unclear what this setting does from the name and description. Is there a more user-friendly name and description?

"When the pool of unplayed tracks drops below this percentage of the total tracks available to AutoDJ, add the least-recently played tracks back into the pool until it is this size." :-/

Copy link
Contributor

Choose a reason for hiding this comment

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

That wasn't my choice -- daschuer suggested this text.

Copy link
Member

Choose a reason for hiding this comment

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

Way to throw @daschuer under the bus :P. I'm not interested in who wrote what. I'm trying to figure out the best phrasing to maximize comprehensibility. Got any ideas?

Copy link
Contributor

Choose a reason for hiding this comment

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

I was just saying that in case your multitude of petty criticisms was somehow directed at me personally (e.g. because I went ahead and implemented a feature that you wanted kiboshed).

Copy link
Member

Choose a reason for hiding this comment

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

There's no rush to merge here -- we're nowhere near our next major release. What you're saying is that you want to be done working on this and I understand that but please work with me to get the code and feature in a good, ready to release state because once it is merged I know from experience that you (i.e. you the general you, contributor of a shiny new feature) won't be as interested in fixing tooltip phrasing.

Regarding style issues -- there are minor pros and cons of various styles but the most important thing is uniformity. When the style is uniform, I can scan a file much easier and generally eyeball the shape of it -- see how the control flows, the exit points, blocks, etc. I'm sorry for the tedious style comments but they are an important part of a healthy codebase.

Copy link
Contributor

Choose a reason for hiding this comment

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

Re: rush to merge...the longer we go without merging, the more work I have to do to keep up with trunk changes that affect my code (e.g. getting rid of the top-level mixxx directory, which "git merge" handled badly, requiring me to do a LOT of hand-work to make things right again). This is wasted effort.

Re: style comments...in my experience, as long as the code is human-readable, that's more than enough. If one is modifying someone else's code, one should try very hard to mimic the local style, so that the changes don't look jarring next to older code. Anything on top of that is needlessly pedantic.

Copy link
Member

Choose a reason for hiding this comment

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

Yea, that top level change was quite rough. Sorry :-/. There won't be anything that drastic to merge with going forward.

Copy link
Member Author

Choose a reason for hiding this comment

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

@ulatekh: You have forked from a version without the root mixxx folder. daschuer@8e03aa0. So the compassion goes to me ;-)

</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>20</number>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QCheckBox" name="autoDjIgnoreTimeCheckBox">
<property name="toolTip">
<string>Uncheck, to ignore all played tracks.</string>
</property>
<property name="text">
<string>Auto DJ: Suspend track from re-queue</string>
</property>
</widget>
</item>
<item row="12" column="1" colspan="2">
<widget class="QTimeEdit" name="autoDjIgnoreTimeEdit">
<property name="toolTip">
<string>Duration after which a track is eligible for selection by Auto DJ again</string>
</property>
<property name="displayFormat">
<string>hh:mm</string>
</property>
<property name="timeSpec">
<enum>Qt::LocalTime</enum>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
Expand Down
Loading