-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Macros Backend respin #13172
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
base: main
Are you sure you want to change the base?
Macros Backend respin #13172
Conversation
-Ignoring return value of function declared with 'nodiscard' attribute -Missing include
…ter clear, but clear intentional leaves a user specified label untouched
9ac8800 to
d61749c
Compare
acolombier
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried the feature but could only get a single hotcue to work. It could be that I'm not using properly tho. Do you know if there is any wiki or doc on how to use this feature beside the GSoC wiki page?
I think there are only the three GSoC pages in our wiki, and the original PRs of cause. One aim of this feature was to achieve compatibility to Serato Flip, to allow data import from Serato. Therefore I guess, that the Serato Flip feature is similar to use: https://support.serato.com/hc/en-us/articles/203157550-Serato-Flip-User-Guide |
acolombier
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for bringing this feature back to life. Appreciate you didn't write this code but I think there quite a few things that don't line up with our coding guidelines.
Haven't had a chance to test it yet!
| optional uint32 type = 1; | ||
| optional uint64 source_frame = 2; | ||
| optional uint64 target_frame = 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at MacroAction::serialize, should not this be mandatory fields?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familar with protobuf and can't answer this. But I couldn't find any review remark in the predecessor PRs about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, maybe these should be required. Not sure. My understanding of protobuf is that this does not affect the serialized output, just the deserialization code. So we should probably make these required and "downgrade" them to optional only if the becomes necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not with certainty, but until now my rule of thump was that everything should be optional just in case. In protobuf 3 the concept of required fields has been removed altogether:
https://stackoverflow.com/questions/31801257/why-required-and-optional-is-removed-in-protocol-buffers-3
f0ebdab to
f9847d9
Compare
544ba01 to
18c6730
Compare
b953cf0 to
53e8d61
Compare
|
I thought macros are per track? (= per deck, not one macro manager. |
|
The GUI controls are global, you click the record button and it records the deck were the DJ does the next action. I also thought, that this might be difficult to understand and had the idea of a colored border around the deck - e.g. when armed, all decks get a orange border, and once a deck is selected, only this one get a red border. |
|
But (as I understood it back then) macros are per track, so I can start a macro on deck1, load a track in deck2 and start its macro#5 to do prepared mashups and stuff. I don't want to move this off-topic, just saying... |
|
Yes, lets discuss the GUI on Zulip. The COs in this PRs should be flexible enough to allow per deck controls as well. |
|
Great you picked this up. What is the difference between the Status::Playing and Status::Enabled? I have not tested it ... Am I right that Macros do not necessarily include transport actions? Will the track start playing if pressing macro play? This depends probably on the macro itself? |
-Use QStringLiteral: in getConfigKey instead of QString member -Avoiding multiple calls to getConfigKey by using a lambda function
See https://github.com/mixxxdj/mixxx/wiki/Macros |
|
Unfortunately I have not yet understand the difference and the underlying use case. Can you explain it? |
There is no mixxx/src/engine/controls/macrocontrol.h Lines 24 to 31 in 3ea8edd
|
Oh I see, I got confused with the I have still not fully understand how that interacts. Is the a description of the state transitions somewhere? For my understanding a macro is comparable to Auto DJ, but only for a single track. Is that correct? It is possible to record a jump between two cue points. Is that correct? |
|
I don't see a similarty to AutoDJ, but yes, it's per track. I added a video that explains the functionality to the PR description. And please let not put the feature in question at all. It's all defined and lengthy discussed in GSoC. This is just to fix the final code style and and unit test issues, which prevented merging of the original PR. |
3f2c892 to
20e55d0
Compare
ba4dc9f to
faa76d0
Compare
Swiftb0y
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couple comments to try and help get this along.
| int value() const { | ||
| return m_value; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this breaks the encapsulation which is the sole purpose of this class. If the value is used in queries, I think its supposed to go through the QVariant (you may need to look at other usages of DbId).
| for (const MacroPointer& pMacro : std::as_const(m_macros)) { | ||
| if (pMacro->isDirty()) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::any_of
| /// but that is subject to change. | ||
| class MacroAction { | ||
| public: | ||
| enum class Type : uint32_t { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| enum class Type : uint32_t { | |
| enum class Type { |
| /// | ||
| /// Note that currently only jumps to a m_target position are available, | ||
| /// but that is subject to change. | ||
| class MacroAction { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trivial constexpr opportunity of the class.
| #include "audio/frame.h" | ||
| #include "engine/engine.h" | ||
| #include "proto/macro.pb.h" | ||
| namespace proto = mixxx::track::io; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
namespace pollution in header
| namespace proto = mixxx::track::io; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The suggested code change breaks the build
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, you'll obviously have to replace all the occurences of proto with the longer name...
| m_COStatus([this]() { return getConfigKey("status"); }()), | ||
| m_CORecord([this]() { return getConfigKey("record"); }()), | ||
| m_COPlay([this]() { return getConfigKey("play"); }()), | ||
| m_COEnable([this]() { return getConfigKey("enable"); }()), | ||
| m_COLoop([this]() { return getConfigKey("loop"); }()), | ||
| m_activate([this]() { return getConfigKey("activate"); }()), | ||
| m_toggle([this]() { return getConfigKey("toggle"); }()), | ||
| m_clear([this]() { return getConfigKey("clear"); }()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is dubious because it relies on the class already being partially initialized. I think the better option would be to just pass in the group along with getConfigKey and make it static...
|
|
||
| m_updateRecordingTimer.moveToThread(qApp->thread()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this needs a comment.
| // FIXME(xeruf) Jumps while paused (e.g. via GotoAndStop) are not properly recorded | ||
| // since this function is not called |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you plan to address these FIXMEs? These certainly sound like bugs.
| /// The unquantized FramePos of a jump that is yet to be processed | ||
| mixxx::audio::FramePos m_queuedJumpTarget; | ||
|
|
||
| rigtorp::SPSCQueue<MacroAction> m_recordedActions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since this is designed for multithreading, this suggests that MacroControl is also used from multiple threads. Its not clear to me how though so I'd appreciate if you could document which member functions are expected to be accessed concurrently (and thus need to be threadsafe and which dont).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MacroControl obviously lives in the GUI thread, but IIRC some methods (e.g., slotJumpQueued) are invoked via direct connection from the engine thread.
666998f to
faa76d0
Compare
This is #4528 with fixed CI and solved merge conflicts.
It implements the following COs without GUI: https://github.com/mixxxdj/mixxx/wiki/Macros
This PR is the first step to implement the Macro feature. The Mixxx Macros feature is designed functional compatible to Serato Flip. If we later add a Serato Flip importer in a Follow-Up PR, Mixxx DJs can use all files prepared with Flips provided by the common DJ pools.
A good (maybe a bit flippy ;-) ) introduction into the use cases of Serato Flip can be found here: https://www.youtube.com/watch?v=sHRWfdxkI7E&t=186s