One more…
I've tried adapting your Sec:Fr Grid selection command to Musical settings. I used:
sf.ui.proTools.gridSet({
gridValueName: "1/2 Note",
});
However I get the following error: Could not select GridValueName etc… - is that because of the note symbol at the start of the variable in PT?
I also tried a variation of your Nudge script
sf.ui.proTools.gridSet({
value: "0|0|240"
});
Error: Gridvaluename is required.
- Christian Scheuer @chrscheuer2020-03-21 00:25:25.900Z
You need a lowercase 'n' in note, like this:
sf.ui.proTools.gridSet({ gridValueName: '1/4 note' });
- SSimon Franglen @Simon_Franglen
Doh! Apologies for such a numbskull Q
Christian Scheuer @chrscheuer2020-03-21 10:55:24.098Z
No need to apologise :) Now we have a Q/A for how to set musical grid values.
- SSimon Franglen @Simon_Franglen
Since this is a QA for this. I have separate Grid values in the Midi Editor window to the main window. I change these more often than the main edit window. I've managed to create a command that works to select these, however it's very inelegant. I select the group, then click up six times to make sure I end up at the very top of the list, then click down the required amount of times to select the correct note value. Obviously, apart from the brute force method of selecting menu items, it also doesn't check whether the triplet is selected or not. In an ideal world I'd have the all values check whether triplet is checked or not, then allow me to set it separately. Currently I choose the variable once or twice to reset the triplet to the correct value.
Here's the one for 16th triplets.
sf.ui.proTools.windows.whoseTitle.startsWith('MIDI Editor:').first.groups.whoseTitle.is('Grid/Nudge View').first.textFields.whoseTitle.is('Grid Value').first.mouseClickElement(); sf.keyboard.press({ keys: "up", repetitions: 6, fast: true, }); sf.keyboard.press({ keys: "down", repetitions: 4, fast: true, }); sf.keyboard.press({ keys: "return", }); sf.ui.proTools.windows.whoseTitle.startsWith('MIDI Editor:').first.groups.whoseTitle.is('Grid/Nudge View').first.textFields.whoseTitle.is('Grid Value').first.mouseClickElement(); sf.keyboard.press({ keys: "up", repetitions: 6, fast: true, }); sf.keyboard.press({ keys: "down", repetitions: 8, fast: true, }); sf.keyboard.press({ keys: "return", });
Kitch Membery @Kitch2020-03-24 03:32:04.755Z
Hi @Simon_Franglen,
I thought I'd give this one a go. I found a script that @chrscheuer wrote last week (at this link https://forum.soundflow.org/-1490#post-5) and tweaked it to work in the MIDI Editor.
function selectGrid({ value, dotted, triplet }) { var midiGridButton = sf.ui.proTools.windows.whoseTitle.startsWith('MIDI Editor:').first.groups.whoseTitle.is('Grid/Nudge View').first.textFields.whoseTitle.is('Grid Value').first; var gridValue = midiGridButton.value.invalidate().value.replace(/\s/g, ''); if (gridValue !== value) { midiGridButton.popupMenuSelect({ menuPath: [value] }); } var dottedNoteValues = ['0|0|090', '0|0|180', '0|0|360', '0|0|720', '0|1|480', '0|3|000']; var tripletNoteValues = ['0|0|040', '0|0|080', '0|0|160', '0|0|320', '0|0|640', '0|1|320']; function checkIfDotted() { if (dottedNoteValues.indexOf(gridValue) >= 0) return true else return false; } function checkIfTriple() { if (tripletNoteValues.indexOf(gridValue) >= 0) return true else return false; } if (!dotted && !triplet) { if (checkIfTriple()) { midiGridButton.popupMenuSelect({ menuPath: ['triplet'] }); } else if (checkIfDotted()) { midiGridButton.popupMenuSelect({ menuPath: ['dotted'] }); } } else { if (triplet && !checkIfTriple()) { midiGridButton.popupMenuSelect({ menuPath: ['triplet'] }); } else if (dotted && !checkIfDotted()) { midiGridButton.popupMenuSelect({ menuPath: ['dotted'] }); } } } selectGrid({ value: '1/64 note', dotted: true, triplet: false });
My alterations could use some work but it is functional all the same!... All you need to do is change the selectGrid values in the second last line.
Rock on
KitchChristian Scheuer @chrscheuer2020-03-24 06:01:07.671Z
That's beautiful, @Kitch - thanks for sharing :)
Kitch Membery @Kitch2020-03-24 06:13:20.040Z
My pleasure. I have been finding some time to learn more JavaScript & solving questions on the forum is a forced way of learning. :-)
I would love to know how to get an array from that pop up menu text items... Is that possible? The only way I could evaluate the triplets and dotted notes values was to use the Bars|Beats reading.
Christian Scheuer @chrscheuer2020-03-24 07:08:09.704Z
Yes with popupMenuFetchItems - but your code is faster since it doesn't have to open the popup to get the state.
- In reply toSimon_Franglen⬆:
Kitch Membery @Kitch2020-03-24 23:56:00.897Z
Simon... Here's a small update to the script. :-)
function selectGrid({ value, dotted, triplet }) { var midiGridButton = sf.ui.proTools.windows.whoseTitle.startsWith('MIDI Editor:').first.groups.whoseTitle.is('Grid/Nudge View').first.textFields.whoseTitle.is('Grid Value').first; var gridValue = midiGridButton.value.invalidate().value.replace(/\s/g, ''); switch (gridValue) { case '1|0|000': var standardNoteValue = '1 bar'; break; case '0|2|000': var standardNoteValue = '1/2 note'; break; case '0|1|000': var standardNoteValue = '1/4 note'; break; case '0|0|480': var standardNoteValue = '1/8 note'; break; case '0|0|240': var standardNoteValue = '1/16 note'; break; case '0|0|120': var standardNoteValue = '1/32 note'; break; case '0|0|060': var standardNoteValue = '1/64 note'; break; } var dottedNoteValues = ['0|0|090', '0|0|180', '0|0|360', '0|0|720', '0|1|480', '0|3|000']; var tripletNoteValues = ['0|0|040', '0|0|080', '0|0|160', '0|0|320', '0|0|640', '0|1|320']; function checkIfDotted() { if (dottedNoteValues.indexOf(gridValue) >= 0) return true else return false; } function checkIfTriple() { if (tripletNoteValues.indexOf(gridValue) >= 0) return true else return false; } if (!dotted && !triplet) { if (checkIfTriple()) { midiGridButton.popupMenuSelect({ menuPath: ['triplet'] }); } else if (checkIfDotted()) { midiGridButton.popupMenuSelect({ menuPath: ['dotted'] }); } } else { if (triplet && !checkIfTriple()) { midiGridButton.popupMenuSelect({ menuPath: ['triplet'] }); } else if (dotted && !checkIfDotted()) { midiGridButton.popupMenuSelect({ menuPath: ['dotted'] }); } } if (standardNoteValue !== value) { midiGridButton.popupMenuSelect({ menuPath: [value] }); } } selectGrid({ value: '1/16 note', dotted: false, triplet: true });
- SSimon Franglen @Simon_Franglen
Awesome thank you
Kitch Membery @Kitch2020-03-30 06:18:45.794Z2020-03-30 08:12:04.524Z
@Simon_Franglen & @chrscheuer,
I had a little time to test my previous attempt and noticed a few issues so decided to rebuild the script so that it would only change menu when absolutely necessary. The prevous version would sometimes change the tripplet and dotted values twice before getting to the correct setting.
It now works in both the "MIDI Editor"" window and the "Edit:" window depending on which is in focus and check to make sure the popup menu is in Bars|Beats mode.
selectGrid({ //targetNoteValue: '1 bar', targetNoteType: 'Standard' //targetNoteValue: '1/2 note', targetNoteType: 'Standard' //targetNoteValue: '1/4 note', targetNoteType: 'Standard' //targetNoteValue: '1/8 note', targetNoteType: 'Standard' //targetNoteValue: '1/16 note', targetNoteType: 'Standard' //targetNoteValue: '1/32 note', targetNoteType: 'Standard' //targetNoteValue: '1/64 note', targetNoteType: 'Standard' //targetNoteValue: '1/2 note', targetNoteType: 'Dotted' //targetNoteValue: '1/4 note', targetNoteType: 'Dotted' targetNoteValue: '1/8 note', targetNoteType: 'Dotted' //targetNoteValue: '1/16 note', targetNoteType: 'Dotted' //targetNoteValue: '1/32 note', targetNoteType: 'Dotted' //targetNoteValue: '1/64 note', targetNoteType: 'Dotted' //targetNoteValue: '1/2 note', targetNoteType: 'Triplet' //targetNoteValue: '1/4 note', targetNoteType: 'Triplet' //targetNoteValue: '1/8 note', targetNoteType: 'Triplet' //targetNoteValue: '1/16 note', targetNoteType: 'Triplet' //targetNoteValue: '1/32 note', targetNoteType: 'Triplet' //targetNoteValue: '1/64 note', targetNoteType: 'Triplet' }); function selectGrid({ targetNoteValue, targetNoteType }) { //Check to see if the "Edit:" or "MIDI Editor" windows are in focus if (sf.ui.proTools.focusedWindow.title.value.indexOf('Edit: ') === 0) { var gridButton = sf.ui.proTools.windows.whoseTitle.startsWith('Edit:').first.groups.whoseTitle.is('Grid/Nudge Cluster').first.popupButtons.whoseTitle.is('Grid Value').first; } else if (sf.ui.proTools.focusedWindow.title.value.indexOf('MIDI Editor:') === 0) { var gridButton = sf.ui.proTools.windows.whoseTitle.startsWith('MIDI Editor:').first.groups.whoseTitle.is('Grid/Nudge View').first.textFields.whoseTitle.is('Grid Value').first; } else { throw ('Grid popup menu not available'); }; const currentGridDisplay = gridButton.value.invalidate().value.replace(/\s/g, ''); //Check that Grid mode is set to Bars|Beats if (currentGridDisplay.indexOf("|") < 0) { gridButton.popupMenuSelect({ menuPath: ['Bars|Beats'] }); }; //Displayed grid value lookup array var gridDisplayLookup = [ { displayedValue: '1|0|000', noteValue: '1 bar', noteType: 'Standard' }, { displayedValue: '0|2|000', noteValue: '1/2 note', noteType: 'Standard' }, { displayedValue: '0|1|000', noteValue: '1/4 note', noteType: 'Standard' }, { displayedValue: '0|0|480', noteValue: '1/8 note', noteType: 'Standard' }, { displayedValue: '0|0|240', noteValue: '1/16 note', noteType: 'Standard' }, { displayedValue: '0|0|120', noteValue: '1/32 note', noteType: 'Standard' }, { displayedValue: '0|0|060', noteValue: '1/64 note', noteType: 'Standard' }, { displayedValue: '0|3|000', noteValue: '1/2 note', noteType: 'Dotted' }, { displayedValue: '0|1|480', noteValue: '1/4 note', noteType: 'Dotted' }, { displayedValue: '0|0|720', noteValue: '1/8 note', noteType: 'Dotted' }, { displayedValue: '0|0|360', noteValue: '1/16 note', noteType: 'Dotted' }, { displayedValue: '0|0|180', noteValue: '1/32 note', noteType: 'Dotted' }, { displayedValue: '0|0|090', noteValue: '1/64 note', noteType: 'Dotted' }, { displayedValue: '0|1|320', noteValue: '1/2 note', noteType: 'Triplet' }, { displayedValue: '0|0|640', noteValue: '1/4 note', noteType: 'Triplet' }, { displayedValue: '0|0|320', noteValue: '1/8 note', noteType: 'Triplet' }, { displayedValue: '0|0|160', noteValue: '1/16 note', noteType: 'Triplet' }, { displayedValue: '0|0|080', noteValue: '1/32 note', noteType: 'Triplet' }, { displayedValue: '0|0|040', noteValue: '1/64 note', noteType: 'Triplet' }, ]; //Assign Grid Value and Type from lookup var gridNoteValue = gridDisplayLookup.filter(o => o.displayedValue === currentGridDisplay)[0].noteValue; var gridNoteType = gridDisplayLookup.filter(o => o.displayedValue === currentGridDisplay)[0].noteType; //Set note length if (targetNoteValue !== gridNoteValue) { gridButton.popupMenuSelect({ menuPath: [targetNoteValue] }); }; //Toggle Triplet function toggleTriplet() { gridButton.popupMenuSelect({ menuPath: ['triplet'] }); } //Toggle Dotted function toggleDotted() { gridButton.popupMenuSelect({ menuPath: ['dotted'] }); } //Decifer what to toggle to change to the correct target note type if (targetNoteType !== gridNoteType && targetNoteValue !== '1 bar') { if (targetNoteType === 'Triplet' && gridNoteType === 'Standard') { toggleTriplet(); }; if (targetNoteType === 'Triplet' && gridNoteType === 'Dotted') { toggleTriplet(); }; if (targetNoteType === 'Dotted' && gridNoteType === 'Standard') { toggleDotted(); }; if (targetNoteType === 'Dotted' && gridNoteType === 'Triplet') { toggleDotted(); }; if (targetNoteType === 'Standard' && gridNoteType === 'Triplet') { toggleTriplet(); }; if (targetNoteType === 'Standard' && gridNoteType === 'Dotted') { toggleDotted(); }; }; }
All you have to do is un-comment the "targetNoteValue & targetNoteType" line you want by removing the "//" at the start of the line.
The script could also be tailored to work with "Nudge" settings in Bars|Beats mode for both windows by editing the "gridButton" variable.
I think thats it for this one & Thanks again for your help Christian! :-)
Rock on
Kitch- SSimon Franglen @Simon_Franglen
Wonderful! That fixes the one problem I had. Seriously great work and checking the page at the start is a really excellent addition
Kitch Membery @Kitch2020-03-30 21:11:17.194Z
My pleasure mate. Thanks for the kind words. I'm slowly getting the hang of Javascript. As a kid I too started out programing in Basic and then for some reason stopped (probably when I discovered skateboarding) and now I'm back into it I love a good challenge.
Having one shorcut to do both Midi and Edit window is a big plus. I'm sure eventually a Macro will be added to the soundflow Macro editor for this one.
Stay healthy!
- In reply toKitch⬆:NNacho @Nacho_Sotelo
Hello @Kitch! I just found this amazing script and I'm trying to implement it in my workflow.
I'm getting an error on line 72
//Assign Grid Value and Type from lookup var gridNoteValue = gridDisplayLookup.filter(o => o.displayedValue === currentGridDisplay)[0].noteValue;
Im getting:
TypeError: 0 is undefined (Grid line 72))
This happens when the grid is set to anything other than bars beats, so what happens is... If I run this script when the grid is set to timecode, it changes the grid to bars beats and throws the error before changing the actual value.
Kitch Membery @Kitch2020-05-23 00:13:45.392Z
HI Nacho,
Glad you found it helpful mate. I'm on a project right now but I'll take a look at it in the next few days.
BTW... Does your workflow require you to have the Grid value set to timecode all the time?
Rock on!
- NNacho @Nacho_Sotelo
No, I don't have to have the grid value in timecode all the time, its a "just in case" thing, I'm actually already using the script as it is and its working perfectly, I just want to be ready in case I get a session that is set to timecode some day.
Kitch Membery @Kitch2020-05-23 19:49:35.667Z
I've updated the script to switch to bars and beats.
https://forum.soundflow.org/-1717#post-21When I have time... I'll make some changes to switch back to whatever the grid mode was to begin with.
Rock on!
- In reply toNacho_Sotelo⬆:
Kitch Membery @Kitch2020-05-23 09:26:26.246Z2020-05-23 19:46:09.868Z
Here ya go, Nacho!
It was my order of operations was causing the TypeError to be undefined :-)
This version will switch to bars | beats grid mode.
selectGrid({ //targetNoteValue: '1 bar', targetNoteType: 'Standard' //targetNoteValue: '1/2 note', targetNoteType: 'Standard' //targetNoteValue: '1/4 note', targetNoteType: 'Standard' //targetNoteValue: '1/8 note', targetNoteType: 'Standard' //targetNoteValue: '1/16 note', targetNoteType: 'Standard' //targetNoteValue: '1/32 note', targetNoteType: 'Standard' //targetNoteValue: '1/64 note', targetNoteType: 'Standard' //targetNoteValue: '1/2 note', targetNoteType: 'Dotted' //targetNoteValue: '1/4 note', targetNoteType: 'Dotted' //targetNoteValue: '1/8 note', targetNoteType: 'Dotted' //targetNoteValue: '1/16 note', targetNoteType: 'Dotted' //targetNoteValue: '1/32 note', targetNoteType: 'Dotted' targetNoteValue: '1/64 note', targetNoteType: 'Dotted' //targetNoteValue: '1/2 note', targetNoteType: 'Triplet' //targetNoteValue: '1/4 note', targetNoteType: 'Triplet' //targetNoteValue: '1/8 note', targetNoteType: 'Triplet' //targetNoteValue: '1/16 note', targetNoteType: 'Triplet' //targetNoteValue: '1/32 note', targetNoteType: 'Triplet' //targetNoteValue: '1/64 note', targetNoteType: 'Triplet' }); function selectGrid({ targetNoteValue, targetNoteType }) { //Check to see if the "Edit:" or "MIDI Editor" windows are in focus if (sf.ui.proTools.focusedWindow.title.value.indexOf('Edit: ') === 0) { var gridButton = sf.ui.proTools.windows.whoseTitle.startsWith('Edit:').first.groups.whoseTitle.is('Grid/Nudge Cluster').first.popupButtons.whoseTitle.is('Grid Value').first; } else if (sf.ui.proTools.focusedWindow.title.value.indexOf('MIDI Editor:') === 0) { var gridButton = sf.ui.proTools.windows.whoseTitle.startsWith('MIDI Editor:').first.groups.whoseTitle.is('Grid/Nudge View').first.textFields.whoseTitle.is('Grid Value').first; } else { throw ('Grid popup menu not available'); }; //Check that Grid mode is set to Bars|Beats if (gridButton.value.invalidate().value.indexOf("|") < 0) { gridButton.popupMenuSelect({ menuPath: ['Bars|Beats'] }); sf.wait({intervalMs:150}); }; //Get Grid display value as a variable const currentGridDisplay = gridButton.value.invalidate().value.replace(/\s/g, ''); //Displayed grid value lookup array var gridDisplayLookup = [ { displayedValue: '1|0|000', noteValue: '1 bar', noteType: 'Standard' }, { displayedValue: '0|2|000', noteValue: '1/2 note', noteType: 'Standard' }, { displayedValue: '0|1|000', noteValue: '1/4 note', noteType: 'Standard' }, { displayedValue: '0|0|480', noteValue: '1/8 note', noteType: 'Standard' }, { displayedValue: '0|0|240', noteValue: '1/16 note', noteType: 'Standard' }, { displayedValue: '0|0|120', noteValue: '1/32 note', noteType: 'Standard' }, { displayedValue: '0|0|060', noteValue: '1/64 note', noteType: 'Standard' }, { displayedValue: '0|3|000', noteValue: '1/2 note', noteType: 'Dotted' }, { displayedValue: '0|1|480', noteValue: '1/4 note', noteType: 'Dotted' }, { displayedValue: '0|0|720', noteValue: '1/8 note', noteType: 'Dotted' }, { displayedValue: '0|0|360', noteValue: '1/16 note', noteType: 'Dotted' }, { displayedValue: '0|0|180', noteValue: '1/32 note', noteType: 'Dotted' }, { displayedValue: '0|0|090', noteValue: '1/64 note', noteType: 'Dotted' }, { displayedValue: '0|1|320', noteValue: '1/2 note', noteType: 'Triplet' }, { displayedValue: '0|0|640', noteValue: '1/4 note', noteType: 'Triplet' }, { displayedValue: '0|0|320', noteValue: '1/8 note', noteType: 'Triplet' }, { displayedValue: '0|0|160', noteValue: '1/16 note', noteType: 'Triplet' }, { displayedValue: '0|0|080', noteValue: '1/32 note', noteType: 'Triplet' }, { displayedValue: '0|0|040', noteValue: '1/64 note', noteType: 'Triplet' }, ]; //Assign Grid Value and Type from lookup var gridNoteValue = gridDisplayLookup.filter(o => o.displayedValue === currentGridDisplay)[0].noteValue; var gridNoteType = gridDisplayLookup.filter(o => o.displayedValue === currentGridDisplay)[0].noteType; //Set note length if (targetNoteValue !== gridNoteValue) { gridButton.popupMenuSelect({ menuPath: [targetNoteValue] }); }; //Toggle Triplet function toggleTriplet() { gridButton.popupMenuSelect({ menuPath: ['triplet'] }); } //Toggle Dotted function toggleDotted() { gridButton.popupMenuSelect({ menuPath: ['dotted'] }); } //Decifer what to toggle to change to the correct target note type if (targetNoteType !== gridNoteType && targetNoteValue !== '1 bar') { if (targetNoteType === 'Triplet' && gridNoteType === 'Standard') { toggleTriplet(); }; if (targetNoteType === 'Triplet' && gridNoteType === 'Dotted') { toggleTriplet(); }; if (targetNoteType === 'Dotted' && gridNoteType === 'Standard') { toggleDotted(); }; if (targetNoteType === 'Dotted' && gridNoteType === 'Triplet') { toggleDotted(); }; if (targetNoteType === 'Standard' && gridNoteType === 'Triplet') { toggleTriplet(); }; if (targetNoteType === 'Standard' && gridNoteType === 'Dotted') { toggleDotted(); }; }; }
- NNacho @Nacho_Sotelo
Wow!! Thanks a lot! I´m going to try it today
- SIn reply toSimon_Franglen⬆:Simon Franglen @Simon_Franglen
@Kitch That's seriously pretty code. Once upon a time I coded Basic and Pascal… that's how far back I go, I'm starting to learn Java now, looking at the work @chrscheuer and you are doing is really helping me get back in to the saddle
- SSimon Franglen @Simon_Franglen
function checkIfTriple() {
if (tripletNoteValues.indexOf(gridValue) >= 0) return true
else return false;These function checks are something I'm going to use all over the place I'm sure