Numark Mixtrack (Pro) 3 FX mapping change (V1.7)#1014
Numark Mixtrack (Pro) 3 FX mapping change (V1.7)#1014daschuer merged 14 commits intomixxxdj:masterfrom djsteph:Mixtrack-Pro-3-mapping-v1.6
Conversation
…rack-Pro-3-mapping-v1.6
**Bug fixes ** Touch platter + wheel touch speeds up/slows down song when wheel not enabled Corrected Tap button mapping Correct Tap button led behavior when shift lock is active Adjusted mapping of AutoLoop to be identical to Numark user manual, Serato and Virtual DJ, (1, 2, 4, 8) instead of 2, 4, 8, 16 if not shifted and 0.125, 0.25, 0.5, 16 if shifted **FX section Mapping changes** Added InstantFx feature: FX are added to InstantFx by holding Tap and FX button. InstantFx are enabled/disabled directly with the Strip. Tap + FX button: Enables / Disables InstantFx. Strip = Parameter 1 of FXs, TAP + Strip = Super knob Beat knob = parameter 2 of FXs, TAP + Beat knob = Mix ratio PadModeButton + Beat knob = Sampler volumes Shift + BeatKnob = Beat grid move Connected controls for FX enabled Removed soft takeover for Super FX knob (accessed by strip) Removed Callback function for FX Loaded to prevent all parameters from being automatically linked to Super Knob Removed configuration option BeatKnobAsSamplerVolume
Bug fix -InstantFX handling with Shift Key
|
You should clean that 'Merge remote-tracking branch 'refs/remotes/upstream/master' into Mixtrack-Pro-3-mapping-v1.6' away from commits |
|
Have you run static checking tools against this like it's recommended in documentation? |
|
From the forum thread it looks like the functionality is still being decided upon. Shall I wait until you've settled on that for a thorough review? |
|
Agreed. What is currently being decided on is the additional mapping of FX Parameter control. It does add a bit of code to the file, so I will have to clean up that code also. It can be another commit on this pull request, or a new pull request all together. My GitHub skills being weak, I have no idea on how to do the following:
|
No need to open another PR. Just add commit(s) to this branch on your computer, push to this branch of your fork on GitHub, and they will appear on this PR.
Neither do I. @illuusio , could you explain or provide a link that explains? |
Add FX Parameter mapping and correct smartPFL callback New mapping: Deck 1: SHIFT + Treble Knob = FX paramerer 1 - Effect 1 SHIFT + Medium Knob = FX parameter 2 - Effect 1 SHIFT + Bass Knob = Fx parameter 3 - Effect 1 SHIFT + Filter Knob = Fx parameter 4 - Effect 1 Deck 2: SHIFT + Treble Knob = FX paramerer 1 - Effect 2 SHIFT + Medium Knob = FX parameter 2 - Effect 2 SHIFT + Bass Knob = Fx parameter 3 - Effect 2 SHIFT + Filter Knob = Fx parameter 4 - Effect 2 Deck 1: Padmode + Treble Knob = FX paramerer 1 - Effect 3 Padmode + Medium Knob = FX parameter 2 - Effect 3 Padmode + Bass Knob = Fx parameter 3 - Effect 3 Padmode + Filter Knob = Fx parameter 4 - Effect 3 Deck 2: Padmode + Treble Knob = FX paramerer 1 - Effect 4 Padmode + Medium Knob = FX parameter 2 - Effect 4 Padmode + Bass Knob = Fx parameter 3 - Effect 4 Padmode + Filter Knob = Fx parameter 4 - Effect 4
file updates forgotten in previous commit
Eliminate unnecessary object "OnFXButtonControl"
|
@Be-ing , I am confident that you can start reviewing the code. I made final commits and adjusted initial pull request description to reflect all changes made in the past few days. Code changes have been validated with JSHint.com |
| <description>The Numark Mixtrack 3 and Numark Mixtrack Pro 3 are the same controller except that the Pro version has an integrated sound card.</description> | ||
| <forums>http://mixxx.org/forums/viewtopic.php?f=7&t=7286</forums> | ||
| <wiki>http://www.mixxx.org/wiki/doku.php/numark_mixtrack_pro_3</wiki> | ||
| <wiki>http://www.mixxx.org/wiki/doku.php/numark_mixtrack_pro_3</wiki> |
| <script-binding/> | ||
| </options> | ||
| </control> | ||
| <control> |
| <control> | ||
| <group>[Channel1]</group> | ||
| <key>NumarkMixtrack3.InstantFXOff</key> | ||
| <description>Channel 1 strip Instant FX Off</description> |
| <control> | ||
| <group>[Channel2]</group> | ||
| <key>NumarkMixtrack3.InstantFXOff</key> | ||
| <description>Channel 2 strip Instant FX Off</description> |
|
There is a mix of tab and space indentation. |
| if (value===DOWN) { | ||
| deck.TapDown = true; | ||
| bpm.tapButton(decknum); |
There was a problem hiding this comment.
isn't bpm an undefined variable ?
There was a problem hiding this comment.
bpm is from the common controller script. Do I need to redefine it here also?
There was a problem hiding this comment.
Oh, so just declare it in the jshint configuration block on top of file ;)
| engine.setValue(group, 'pfl', true); | ||
| engine.setValue(groupOff, 'pfl', false); | ||
| deck.LEDs["headphones"].onOff(ON); | ||
| deckOff.LEDs["headphones"].onOff(ON); |
|
You can probably merge NumarkMixtrack3.TrebleKnob NumarkMixtrack3.MiddleKnob and NumarkMixtrack3.BassKnob into one function to avoid code duplication. |
| * - Add script to control "volume","filterHigh","filterMid","filterLow" and"crossfader" | ||
| * In order for engine.softTakeover to work for these controls | ||
| * - Add script to control "volume" and"crossfader" | ||
| * in order for engine.softTakeover to work for these controls |
There was a problem hiding this comment.
You can use soft takeover in pure XML:
http://www.mixxx.org/wiki/doku.php/midi_controller_mapping_file_format#input_options
use Soft-takeover modifier
There was a problem hiding this comment.
You can probably merge NumarkMixtrack3.TrebleKnob NumarkMixtrack3.MiddleKnob and NumarkMixtrack3.BassKnob into one function to avoid code duplication
How would you do it?
There was a problem hiding this comment.
You can use the "control" parameter which handles the midino of the control to select which parameter you move.
There was a problem hiding this comment.
Done, I had to include a switch in the function to manage the parameter numbers for EQ and FX has they were not sequencial
| midi.sendShortMsg(control, midino, value); | ||
| } | ||
|
|
||
| function parameterSoftTakeOver (group, control, value) { |
There was a problem hiding this comment.
Why don't you use the built-in soft-takeover ?
http://www.mixxx.org/wiki/doku.php/midi_scripting#soft-takeover
There was a problem hiding this comment.
The soft take over in Mixxx only works with engine.setvalue, not with engine.setparameter. There is a documented request in the launchpad
There was a problem hiding this comment.
Augh. This bug should really be fixed for 2.1...
| new SingleDoubleBtn(NumarkMixtrack3.OnShiftedPFLButton); | ||
| } | ||
| new SingleDoubleBtn(NumarkMixtrack3.OnShiftedPFLButton); | ||
| } |
There was a problem hiding this comment.
must have been a tab that Notepad++ converted
There was a problem hiding this comment.
I don't know about Notepad++, but KWrite/Kate/KDevelop have an option to show dots to indicate trailing spaces. That helps with noticing them before git does.
There was a problem hiding this comment.
Thanks for this tip! I found the option in Notepad++ to show spaces, tabs and all characters
|
|
||
| } | ||
|
|
||
| /* |
There was a problem hiding this comment.
this comment becomes a single-line comment, so please switch to //
|
|
||
| // The duration control is being used to tell if a track has successfully loaded for smartPFL feature | ||
| engine.connectControl("[Channel1]", "duration", "NumarkMixtrack3.OnLoadSelectedTrack"); | ||
| engine.connectControl("[Channel2]", "duration", "NumarkMixtrack3.OnLoadSelectedTrack"); |
There was a problem hiding this comment.
You should use /track_samples/ instead of /duration/ as duration can change when you adjust pitch unless you want to activate PFL on pitch adjustment.
There was a problem hiding this comment.
I just tried that switch to use /track_samples/ instead of /duration/ and the feature stopped working. I also tested modifying the pitch while the other track had PFL on, and no adverse effects occured (activate PFL on pitch adjustment.)
|
New review system stuck to my face got to learn how to use it. Actually rethinking this because there is reviews and stuff. Intrusive git-fu (https://sethrobertson.github.io/GitFixUm/fixup.html) changes thing so drastically that it'll make everyone unhappy. So we have three options neater close this or cherry-pick good commits by hand by someone who has commits rights to Mixxx or we can trust git it solves this as it says: this branch has no conflicts. |
djsteph
left a comment
There was a problem hiding this comment.
I'll clean up the spaces & tabs... Please see my replies to comments in code for explanations.
| * - Add script to control "volume","filterHigh","filterMid","filterLow" and"crossfader" | ||
| * In order for engine.softTakeover to work for these controls | ||
| * - Add script to control "volume" and"crossfader" | ||
| * in order for engine.softTakeover to work for these controls |
| midi.sendShortMsg(control, midino, value); | ||
| } | ||
|
|
||
| function parameterSoftTakeOver (group, control, value) { |
There was a problem hiding this comment.
The soft take over in Mixxx only works with engine.setvalue, not with engine.setparameter. There is a documented request in the launchpad
| new SingleDoubleBtn(NumarkMixtrack3.OnShiftedPFLButton); | ||
| } | ||
| new SingleDoubleBtn(NumarkMixtrack3.OnShiftedPFLButton); | ||
| } |
There was a problem hiding this comment.
must have been a tab that Notepad++ converted
| if (value===DOWN) { | ||
| deck.TapDown = true; | ||
| bpm.tapButton(decknum); |
There was a problem hiding this comment.
bpm is from the common controller script. Do I need to redefine it here also?
| engine.setValue(group, 'pfl', true); | ||
| engine.setValue(groupOff, 'pfl', false); | ||
| deck.LEDs["headphones"].onOff(ON); | ||
| deckOff.LEDs["headphones"].onOff(ON); |
|
It would be nice if we could integrate JSHint into Travis. |
| var deck = NumarkMixtrack3.decks["D" + decknum]; | ||
|
|
||
| if(!deck.shiftKey && !deck.PADMode ) { | ||
| parameterSoftTakeOver ("[EqualizerRack1_[Channel"+ [decknum] +"]_Effect1]", "parameter3", value); |
There was a problem hiding this comment.
Why is decknum in brackets here?
| } | ||
| }; | ||
|
|
||
| //parameterSoftTakeOver (group, control, value) |
There was a problem hiding this comment.
This looks like experimental code that you forgot to remove.
| } | ||
| } | ||
| } else { | ||
| for (i = 5; i <= 8; i++) { |
There was a problem hiding this comment.
You don't need duplicate code in an if...else here. Just use (i = 1 + 4 * decknum; i <= 4 * decknum; i++) for the loop.
There was a problem hiding this comment.
Not sure I get it the magic of what you are teaching me... The if statement is related to which deck is the knob used from. What this is doing is if it is deck 1, then adjust gain of samplers 1-4, if deck 2, adjust gain of samplers 5-8.
If I read properly, the variable "i" will always have the same value, so only the gain of samplers 1-4 would be affected, or all 8 samplers...
There was a problem hiding this comment.
No, the i variable will have a different value depending on the deck. Looking at this again, it would be clearer to define a variable so the for loop expression doesn't become so complicated (and I messed up the math before):
var startingSampler = 1 + 4 * (decknum - 1);
for (i = startingSampler; i <= startingSampler + 4; i++) {
...
There was a problem hiding this comment.
Thanks.. I think I got it... That made a huge chunk of code go away!
| * first 4 values used for Autoloop Not shifted | ||
| * last 4 values used for Autoloop Shifted | ||
| **************************/ | ||
| var loopsize = [1, 2, 4, 8, 0.125, 0.25, 0.5, 16]; |
There was a problem hiding this comment.
The jump from .5 to 16 seems kinda odd. That's really how Serato does it?
There was a problem hiding this comment.
DJ Intro (Serato) and VDJ do not have Shift + Auto Loop values; they only have 1, 2, 4, 8.
I picked 1/8, 1/4, 1/2 and 16 for shift as those were the other values available on the UI for the Shift values. My trial for Serato DJ (the full version) is expired so I can't confirm for that one. But here are the links to the documented mapping by each:
http://www.virtualdj.com/documents/Numark%20Mixtrack%203%20-%20VirtualDJ%208%20Operation%20Guide.pdf and https://www.numark.com/images/product_downloads/MixtrackPro3-UserGuide-v1.1.pdf
There was a problem hiding this comment.
It may make more sense to break from their mappings for this. What do you think of 2, 4, 8, 16 beats unshifted and 1, 1/2, 1/4, 1/8 beats shifted?
There was a problem hiding this comment.
The way I coded it makes it really easier for anyone to adjust as they wish in the config. PCDJ has it as 1/, 1, 4 and 16 not shifted so I tend to think that it is a matter of personal preference. I'm OK to commit as you say,
| for (i = 1; i <= 3; i++) { | ||
|
|
||
| if (deck.TapDown) { | ||
| gainValue[i-1] = engine.getParameter("[EffectRack1_EffectUnit" + [i] + "_Effect1]", "parameter2"); |
Clean up of code and review comments incorporated
|
Thank you for this work, I've used these mappings and had no problems! |
|
Hello Be,
Not sure how the new effect interface would impact this. The only thing
that I see could change is the soft takevover fix for the parameters you
implemented, but I think the code I made to handle that could remain in the
mapping for backward compatibility, Other than that, the mapping already
manages the 2 different methods that are used for effects currently.
Steph
…On Tue, Dec 20, 2016 at 1:05 PM, Be ***@***.***> wrote:
Apologizes if this wasn't clear, but I'm holding off on reviewing this
until the new effects interface in #1063
<#1063> and #1062
<#1062> is merged. If you'd like to
contribute to those design discussions with how you think the Mixtrack Pro
3 could be mapped to the new system, please chime in.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1014 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AQDKya3iN1SJwt1Zo3_GYsV6V57z5XtUks5rKBj1gaJpZM4J_e6B>
.
|
|
The new effects interface introduces a new CO, [EffectUnitX_EffectY],meta that acts like a superknob for each effect in an EffectUnit. This will allow the mapping make use of effect chains. |
|
I don't have plans to change this mapping further. I would prefer if it can
be incorporated in Github such that if someone want to help they will be
able to
Stéph
…On Tue, Dec 20, 2016 at 1:18 PM, Be ***@***.***> wrote:
The new effects interface introduces a new CO, [EffectUnitX_EffectY],meta
that acts like a superknob for each effect in an EffectUnit. This will
allow the mapping make use of effect chains.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#1014 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AQDKycNrjZX5YVhndY6Na4LsJeT4Sb4Cks5rKBwOgaJpZM4J_e6B>
.
|
|
@radusuciu , would you be interested in modifying this mapping for the new effects UI? |
|
To honest, I am not sure how you would see the new configuration mapped on this controller. How would you map it? Currently each deck is mapped to its own effect unit and each fx button is mapped to its own effect in that specific unit. The strip is mapped to the super button. |
|
Map the buttons to selecting [EffectUnitX],focused_effect. Map the touch strip to the meta knob for the focused effect. If no effect is focused, the touch strip controls the superknob. This mode could be entered by pressing the button for the focused effect when it is already focused. Map shift + the buttons to enabling/disabling each effect. I don't think this controller has enough physical controls for it to be useful to map different behavior depending on [EffectUnitX],show_parameters. It may be helpful to switch around which behavior of the buttons is default and which is shifted. I feel it is annoying to have LEDs flicker when shift is pressed, so the LEDs should reflect either the focus selection or the effect enable switches, but not both. I think it will take trying both ways to decide which is better. |
|
I may be able to help with this, but wouldn't it be better to have those pull requests resolved and merged before starting to change up mappings? Currently the effect buttons work such that pressing the button turns an effect on and off from a chain, with one unit per deck, and 4 effects per unit. Shift + effect button is mapped to selecting effects. This behaviour is also etched into the controller itself, and so it may be a bit confusing if re-mapped. |
Yes, it would. Sorry if that wasn't clear.
On second thought, keeping the enable/disable switches as the default layer would probably be most useful.
It is okay to deviate from the labels on the controller a bit. It is nice to be able to scroll through the available effects from the controller, but generally that is something that is set up before using the effects, so it doesn't really need to be accessible from a controller. Is the "beats" encoder a push encoder (does it send a signal when it is pressed)? |
|
Beats knob is a infinite rotary knob that sends value 0 or 1 depending on the direction it is turned. It cannot be pushed. |
|
Isn't the new focus proposal very similar to the "Instant FX" feature as implemented for this controller?
|
Yes, but the current implementation of Instant FX does not allow control of individual effects. It can only control them all together (through the superknob). |
|
Having just played with this a bit, the current implementation feels pretty nice as it turns off when you stop touching the strip. This could also be accomplished with the new effects rack setup but it would be a bit less smooth. Unless I misunderstand, you'd either have to swipe it down, or hit a button, or have some sort of configurable option. |
IMO, the only change that may make some sense, it to map the strip to active FXs Super knob instead of the effect unit super knob. But since there is only one strip to use with the 3 FX button, as soon as you enable more than one effect, you are in fact producing a very similar result as the current mapping produces with the Effect Unit super knob; so I see no real benefit to change this. If there were a knob per FX, then it would make sense to change the mapping, but this is not the case with this controller.
The only time LED will flash is if you activate InstantFX, so that you can tell that the effect is not simply activated. (Solid On). I did pay close attention to limit flashing LEDs to the strict essential. We normally have a light show on the dance floor, I don't need one in front of me on top of it :) |
|
Instant FX and controlling individual effects' metaknobs are mutually exclusive; the controller has to do one or the other at a time. I think I have come up with a way where either mode could be selected. Use tap button + turning the beats encoder to select the focused effect whose metaknob the touchstrip would control. If an effect is focused, turn off Instant FX. If the user scrolls up before the first effect or down past the last effect, revert to controlling the superknob and set [EffectRack1_EffectX],focused_effect to 0. Instant FX would still be available the same way it is currently. If Instant FX is active, unfocus the effect if there is one focused (set [EffectRack1_EffectX],focused_effect to 0). |
|
I can commit to working to adapt this mapping for the new effect rack setup once that is merged if djsteph is not interested. |
|
Can someone merge this now? Adding support for the new effects UI can come in another PR. |
|
Thank you for all the work! |
|
The new effects UI allowing better control of effect chains has been merged. So far only the Deere skin has been updated, but the other skins will be updated for 2.1 too. @djsteph and/or @radusuciu, would you like to contribute an updated mapping? You can find documentation about what has changed for mapping controllers on the wiki. |
|
Hello Radu,
I don't have plans to modify the mapping. The latest version has been
merged in GIT, you can apply the modifications required. The temporary
functions for parameter soft takeover can be replaced with the proper
softtakeover. For the new effect setup, I'll let you decide the best use of
the controller.
Thanks
Steph
…On Fri, Feb 3, 2017 at 4:27 PM, Radu Suciu ***@***.***> wrote:
@Be-ing <https://github.com/Be-ing> I'd be willing to contribute but
would defer to @djsteph <https://github.com/djsteph>.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1014 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AQDKycSU01murM7nusYM8BmddAu2xhvnks5rY5vNgaJpZM4J_e6B>
.
|
|
My general suggestion is to use the effect buttons in combination with some modifier, whether that's shift or the tap button or whatever, to set [EffectRack1_EffectUnitX],focused_effect. Pressing that again for the focused effect should set focused_effect back to 0. When an effect is focused, make the touch strip control that effect's metaknob; when no effect is focused, control the superknob as before. If the Instant FX feature is enabled, unfocus and control the superknob. |
|
I have a suggestion to simplify the mapping and use both Instant FX and the new effect focusing. Instead of assigning effects to Instant FX, make Instant FX mode a binary toggle switch. When Instant FX is on, touching the touchstrip would enable the focused effect and manipulate its metaknob. If no effect was focused when Instant FX is on, touching the touchstrip would enable any effects that are disabled and manipulate the superknob. This would allow the mapping for the effect buttons to be straightforward and remain similar to how they are now: Press with no modifier: toggle effect enable switch I'm not sure where the toggle switch for Instant FX mode would fit in. Maybe pressing and holding the Tap button? |
|
Will try and take a look at this tonight. Thanks for suggestions @Be-ing! |
|
I think I will use what Be outline above, including the Instant FX toggle with Tap long-press. I also agree that it would be most intuitive if focused effects map directly to Instant FX. When the Tap button is held, Instant FX mode will be toggled, and all focused effects will have their LEDs flash, the same as in the mapping now.
This part I think is less intuitive. If no effects are focused, and Instant FX is toggled on, do we just light up all of the available effect buttons? And if a user then focuses on an effect, do all the other ones turn off? I think I could get used to that but I'm not sure it's necessary. Currently, you have to make a deliberate choice to add an effect to Instant FX, and I think that that's fine. Input appreciated, otherwise, will submit PR with above functionality. By the way, I really like the way the new Effects rack looks/works in Deere. It feels a lot more practical. |
That might be a better idea than what I suggested.
No, the point of focusing effects is not to have a bunch of effects to switch between. The point is to be able to chain effects and control them individually. Changing the focus should not do anything to the enable switches.
:) |
|
If you were wondering, I don't think there would be any point in making the Mixtrack Pro 3 mapping work differently depending on the state of show_parameters. That is meant for controllers with more knobs. |
Code changes have been validated with JSHint.com
Bug fixes
Touch platter + wheel touch speeds up/slows down song when wheel not enabled
Corrected Tap button mapping
Correct Tap button led behavior when shift lock is active
Missing callback function for smartPFL to work properly if track is loaded directly on UI
Adjusted mapping of AutoLoop to be identical to Numark user manual, Serato and Virtual DJ,
(1, 2, 4, 8) instead of 2, 4, 8, 16 if not shifted and 0.125, 0.25, 0.5, 16 if shifted
FX section Mapping changes
Added InstantFx feature: FX are added to InstantFx by holding Tap and FX button. InstantFx are enabled/disabled directly with the Strip.
Tap + FX button: Enables / Disables InstantFx.
Strip: Super effect. If Instant FX is activated for an FX, also enables / disables that FX
Shift + Strip: Fast Seek (already mapped)
Tap button + Strip FX paramerer 1 - Effects 1, 2 and 3
Beat knob: Mix/ratio
TAP + Beat knob = parameter 2 of FX 1, 2 and 3
Shift + Beat knob: Beat grid move
Pad Mode + Beat knob: Sampler volumes (deck 1= 1-4; deck 2 = (5-8)
Tap Button: well.. Tap button.
Deck 1:
SHIFT + Treble Knob = FX paramerer 1 - Effect 1
SHIFT + Medium Knob = FX parameter 2 - Effect 1
SHIFT + Bass Knob = Fx parameter 3 - Effect 1
SHIFT + Filter Knob = Fx parameter 4 - Effect 1
Deck 2:
SHIFT + Treble Knob = FX paramerer 1 - Effect 2
SHIFT + Medium Knob = FX parameter 2 - Effect 2
SHIFT + Bass Knob = Fx parameter 3 - Effect 2
SHIFT + Filter Knob = Fx parameter 4 - Effect 2
Deck 1:
Pad Mode + Treble Knob = FX paramerer 1 - Effect 3
Pad Mode + Medium Knob = FX parameter 2 - Effect 3
Pad Mode + Bass Knob = Fx parameter 3 - Effect 3
Pad Mode + Filter Knob = Fx parameter 4 - Effect 3
Deck 2:
Pad Mode + Treble Knob = FX paramerer 1 - Effect 4
Pad Mode + Medium Knob = FX parameter 2 - Effect 4
Pad Mode + Bass Knob = Fx parameter 3 - Effect 4
Pad Mode + Filter Knob = Fx parameter 4 - Effect 4
Other changes
Connected controls for FX enabled
Removed soft takeover for Super FX knob (accessed by strip)
Removed Callback function for FX Loaded to prevent all parameters from being automatically linked to Super Knob
Removed configuration option BeatKnobAsSamplerVolume
Included Parameter soft taker over function