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

Enable setting hotcue color via controlobject #2016

Conversation

ferranpujolcamins
Copy link
Contributor

@ferranpujolcamins ferranpujolcamins commented Jan 30, 2019

Supersedes #1830 (thanks @Swiftb0y for your work!)

  • There's a "No Color" color. Skins will be allowed to provide a fall-back color to render cues with this color.
  • Cue colors are now represented by an id number in COs and DB. This will allow us to safely change the color names and Hex code in the future without braking users cues.
  • Adjustments to hotcue mark rendering

TODO:

  • Expose PredefinedColor to ControllerEngine and provide appropriate api
    • Test with a controller
  • Profile a little bit to make sure we don't hit on performance too much
  • Check if we need some final color adjustments
  • Allow skins to define a fall-back color for No Color cues
    • Add docs to wiki
  • Better code comments on util/color

Swiftb0y and others added 30 commits October 2, 2018 16:31
@ferranpujolcamins
Copy link
Contributor Author

What about controller mappings? Shall we adapt the mappings of controllers with rgb pads to reflect the cue colors before releasing 2.3?

@ferranpujolcamins
Copy link
Contributor Author

Shall I rebase this on 2.3 branch and issue a PR to it?

@Swiftb0y
Copy link
Member

What about controller mappings? Shall we adapt the mappings of controllers with rgb pads to reflect the cue colors before releasing 2.3?

Is @dszakallas still willing to work on his launchpad mapping?
I just got my new Numark NS6II in the Mail which features RBG pads, so I guess that could be one of the first controllers with native RGB integration.

@dszakallas
Copy link
Contributor

I'm not fully grasping this feature. Is this about assigning different colors to different hot cue markers?

@Swiftb0y
Copy link
Member

Yes exactly. It has been standard in most other DJing Applications and it is IMO essential for most people. There is a reason why almost every modern Controller has RGB Pads (including the latest launchpad generation ;) )

@daschuer
Copy link
Member

What about controller mappings? Shall we adapt the mappings of controllers with rgb pads to reflect the cue colors before releasing 2.3?

This would be a only a nice to have. I hope this will attract attention at the original mapper, and maybe they are willing to do the work.

@daschuer
Copy link
Member

Shall I rebase this on 2.3 branch and issue a PR to it?

We have no 2.3 branch yet. So it is just fine.

@dszakallas
Copy link
Contributor

This definitely sounds like a cool feature. I'm happy to add it to the my Launchpad mapping.

@daschuer daschuer changed the title [WIP] Enable setting hotcue color via controlobject Enable setting hotcue color via controlobject Feb 13, 2019
@daschuer
Copy link
Member

LGTM
Thank you @Swiftb0y and @ferranpujolcamins and all others involved.
It is great that we have finally made this really good! :-)

@daschuer daschuer merged commit 4c2f240 into mixxxdj:master Feb 13, 2019
@Swiftb0y
Copy link
Member

I'm really happy that we finally finished this PR. Especially, @ferranpujolcamins, thank you for continuing what I've started. Now we just have to think about how to make this usable by exposing it to the Skins.

@ferranpujolcamins ferranpujolcamins deleted the Enable-Setting-hotcue-color-via-controlobject branch February 15, 2019 21:57
@ywwg
Copy link
Member

ywwg commented Mar 5, 2019

I am getting crashes in mixxx and a git bisect identifies commit 29df355 as the culprit. This happens when I just load any track into deck 1.

backtrace:

#0  0x00007ffff62f7df7 in QMutex::lock() () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#1  0x00005555557c686f in QMutexLocker::QMutexLocker(QBasicMutex*) (m=0x10, this=<synthetic pointer>) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qmutex.h:206
#2  0x00005555557c686f in Track::getCuePoints() const (this=0x0) at src/track/track.cpp:799
#3  0x00005555558560f3 in WOverview::onMarkChanged(double) (this=0x55555da13b90) at /usr/include/c++/8/bits/shared_ptr_base.h:996
#4  0x00007ffff64d6830 in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#5  0x00005555558b3f50 in ControlProxy::valueChanged(double) (this=<optimized out>, _t1=<optimized out>) at lin64_build/src/control/moc_controlproxy.cc:163
#6  0x00007ffff64d6830 in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#7  0x00005555558b3b0c in ControlDoublePrivate::valueChanged(double, QObject*) (this=this@entry=0x5555587474c0, _t1=<optimized out>, _t1@entry=9512, _t2=<optimized out>)
    at lin64_build/src/control/moc_control.cc:140
#8  0x00005555558ad739 in ControlDoublePrivate::setInner(double, QObject*) (this=this@entry=0x5555587474c0, value=9512, pSender=pSender@entry=0x555558a0d5c0) at src/control/control.cpp:198
#9  0x00005555558ad7d9 in ControlDoublePrivate::set(double, QObject*) (this=0x5555587474c0, value=<optimized out>, value@entry=9512, pSender=0x555558a0d5c0) at src/control/control.cpp:185
#10 0x0000555555d5e727 in ControlProxy::set(double) (v=9512, this=<optimized out>) at src/control/controlproxy.h:134
#11 0x0000555555d5e727 in BaseTrackPlayerImpl::loadTrack(std::shared_ptr<Track>) (this=0x5555583f7860, pTrack=...) at src/mixer/basetrackplayer.cpp:188
#12 0x0000555555d5f358 in BaseTrackPlayerImpl::slotLoadTrack(std::shared_ptr<Track>, bool) (this=0x5555583f7860, pNewTrack=
    std::shared_ptr<class Track> (use count 12, weak count 1) = {...}, bPlay=<optimized out>) at /usr/include/c++/8/ext/atomicity.h:96
#13 0x0000555555a7de2b in PlayerManager::slotLoadTrackToPlayer(std::shared_ptr<Track>, QString, bool)
    (this=0x555558577ff0, pTrack=std::shared_ptr<class Track> (use count 12, weak count 1) = {...}, group=..., play=<optimized out>) at /usr/include/c++/8/ext/atomicity.h:96
#14 0x0000555555a7025f in PlayerManager::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>)
    at /usr/include/c++/8/ext/atomicity.h:96
#15 0x00007ffff64d66db in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#16 0x0000555555a377fb in Library::loadTrackToPlayer(std::shared_ptr<Track>, QString, bool)
    (this=<optimized out>, _t1=std::shared_ptr<class Track> (use count 12, weak count 1) = {...}, _t2=..., _t3=<optimized out>) at lin64_build/src/library/moc_library.cc:435
#17 0x0000555555a25114 in Library::slotLoadTrackToPlayer(std::shared_ptr<Track>, QString, bool)
    (this=<optimized out>, pTrack=std::shared_ptr<class Track> (use count 12, weak count 1) = {...}, group=..., play=play@entry=false) at /usr/include/c++/8/ext/atomicity.h:96
#18 0x0000555555a37f6f in Library::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>)
    at /usr/include/c++/8/ext/atomicity.h:96
#19 0x00007ffff64d66db in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#20 0x0000555555b90f7b in WLibraryTableView::loadTrackToPlayer(std::shared_ptr<Track>, QString, bool) (this=<optimized out>, _t1=..., _t2=..., _t3=<optimized out>)
    at lin64_build/src/widget/moc_wlibrarytableview.cc:210
#21 0x0000555555882cc1 in WTrackTableView::loadSelectionToGroup(QString, bool) (this=0x5555723f1540, group=..., play=<optimized out>) at /usr/include/c++/8/ext/atomicity.h:96
#22 0x0000555555882efb in virtual thunk to WTrackTableView::loadSelectedTrackToGroup(QString, bool) () at /usr/include/c++/8/bits/atomic_base.h:295
#23 0x0000555555a2bcff in LibraryControl::slotLoadSelectedTrackToGroup(QString, bool) (this=<optimized out>, group=..., play=<optimized out>) at /usr/include/c++/8/bits/atomic_base.h:295
#24 0x0000555555a38ffc in LibraryControl::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>)
    at /usr/include/x86_64-linux-gnu/qt5/QtCore/qrefcount.h:60
#25 0x00007ffff64d66db in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#26 0x0000555555a38e43 in LoadToGroupController::loadToGroup(QString, bool) (this=<optimized out>, _t1=..., _t2=<optimized out>, _t2@entry=false)
    at lin64_build/src/library/moc_librarycontrol.cc:141
#27 0x0000555555a2b9de in LoadToGroupController::slotLoadToGroup(double) (this=<optimized out>, v=<optimized out>) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qrefcount.h:60
#28 0x0000555555a38eed in LoadToGroupController::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)
    (_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=<optimized out>) at lin64_build/src/library/moc_librarycontrol.cc:85
#29 0x00007ffff64d66db in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#30 0x00005555558b3d60 in ControlObject::valueChanged(double) (this=<optimized out>, _t1=<optimized out>) at lin64_build/src/control/moc_controlobject.cc:143
#31 0x00007ffff64d66db in QMetaObject::activate(QObject*, int, int, void**) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#32 0x00005555558b3b0c in ControlDoublePrivate::valueChanged(double, QObject*) (this=this@entry=0x55555a077fe0, _t1=<optimized out>, _t1@entry=1, _t2=<optimized out>)
    at lin64_build/src/control/moc_control.cc:140
#33 0x00005555558ad739 in ControlDoublePrivate::setInner(double, QObject*) (this=this@entry=0x55555a077fe0, value=1, pSender=pSender@entry=0x0) at src/control/control.cpp:198
--Type <RET> for more, q to quit, c to continue without paging--
#34 0x00005555558ad7d9 in ControlDoublePrivate::set(double, QObject*) (this=0x55555a077fe0, value=<optimized out>, pSender=0x0) at src/control/control.cpp:185
#35 0x00005555558adc0b in ControlDoublePrivate::setValueFromMidi(MidiOpCode, double) (this=0x55555a077fe0, opcode=<optimized out>, midiParam=<optimized out>) at src/control/control.cpp:248
#36 0x00005555558cfbf3 in KeyboardEventFilter::eventFilter(QObject*, QEvent*) (this=0x5555566a4e50, e=0x7fffffffd900) at src/controllers/keyboard/keyboardeventfilter.cpp:67
#37 0x00007ffff64ad1ab in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#38 0x00007ffff6f3f491 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#39 0x00007ffff6f47a69 in QApplication::notify(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#40 0x00007ffff64ad499 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#41 0x00007ffff6f9ae79 in  () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#42 0x00007ffff6f3f4a1 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#43 0x00007ffff6f46ae0 in QApplication::notify(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#44 0x00007ffff64ad499 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#45 0x00007ffff697fd98 in QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#46 0x00007ffff6985415 in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#47 0x00007ffff695fb6b in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5
#48 0x00007fffe65c4e5b in  () at /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
#49 0x00007ffff64ac16b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#50 0x00007ffff64b42e2 in QCoreApplication::exec() () at /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#51 0x00005555556bd34c in (anonymous namespace)::runMixxx (args=..., app=0x7fffffffdb70) at src/main.cpp:53
#52 0x00005555556bd34c in main(int, char**) (argc=<optimized out>, argv=<optimized out>) at src/main.cpp:136

#2 0x00005555557c686f in Track::getCuePoints() const (this=0x0) at src/track/track.cpp:799
#3 0x00005555558560f3 in WOverview::onMarkChanged(double)

getCuePoints is called on a nullptr m_pCurrentTrack

@Swiftb0y
Copy link
Member

Swiftb0y commented Mar 5, 2019

I can not reproduce that. I checked out the mentioned commit directly and built it with no extra flags. I can load any track into any Deck and Mixxx stays stable.

@ywwg
Copy link
Member

ywwg commented Mar 5, 2019

It doesn't happen 100% of the time, and it looks like it can only crash on the first try. And I'm guessing this only happens on tracks that have hotcues set.

What's going on is m_pCurrentTrack is null at construction time. When a track is loaded, some of the signals are crossed so that onMarkChanged is getting called before slotLoadingTrack is called. Therefore, once any track loads correctly, m_pCurrentTrack will never be null again so the crash is avoided. But also, I suspect onMarkChanged is always getting called for the old track, not the current one. onMarkChanged seems to be called by pmark->connectSamplePositionChanged signal. I'm not sure what event is triggering the sample position changes though.

@ywwg
Copy link
Member

ywwg commented Mar 5, 2019

ok so this only occurs on tracks where a loop has been defined. So here are the reproduce instrux:

  1. Start mixxx fresh
  2. Load a track that already has a loop defined
  3. crash

The trigger to the crash is basetrackplayer.cpp where it calls m_pLoopInPoint->set(loopStart); -- setting the loop start position triggers the sample position changed signal early, before the track pointer in woverview.cpp has been updated yet. It may just be enough to put a nullptr check around the access of m_pCurrentTrack in woverview.cpp, but I'm trying to figure out if there are any bad side effects to this misordering.

@ywwg
Copy link
Member

ywwg commented Mar 5, 2019

@Swiftb0y
Copy link
Member

Swiftb0y commented Mar 5, 2019

I still can't reproduce the crash...
Maybe I'm doing something wrong screencast
The Build is exactly from the commit you said which introduced the Issue.

@ywwg
Copy link
Member

ywwg commented Mar 5, 2019

try building from head, not from that commit. I think that commit just shows where the signal was hooked up. Also try with the latenight skin just in case that makes a difference somehow?

@Swiftb0y
Copy link
Member

Swiftb0y commented Mar 5, 2019

Yes, It only happens with the LateNight skin. All of the other Skins are fine.

@ywwg
Copy link
Member

ywwg commented Mar 5, 2019

@ywwg
Copy link
Member

ywwg commented Mar 5, 2019

I'll file a bug since this is tricky

@Swiftb0y
Copy link
Member

Swiftb0y commented Mar 5, 2019

https://www.youtube.com/watch?v=ZYicH0u-BFo

the video is inaccessible. (private instead of unlisted?)

@ywwg
Copy link
Member

ywwg commented Mar 5, 2019

ah, yes, was private. Looks like you're able to repro now though

bug:
https://bugs.launchpad.net/mixxx/+bug/1818714

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants