Lag when pressing Stream Deck Advanced Locations
Title
Lag when pressing Stream Deck Advanced Locations
What do you expect to happen when you run the script/macro?
I currently have three presets I've set up within the Advanced Memory Locations Template. CLICK, NOISE and POP. Whenever I press these on my Stream Deck within big session they are very slow to load within Pro Tools. I have a lag of around 10/12 seconds.
However, if I add a memory location manaully it's super fast. The problem does not persist in smaller sessions.
Thanks in advance
Peter
Are you seeing an error?
What happens when you run this script?
When I press the button on Stream Deck to activate the macros, it's as if I haven't pressed anything. There's a delay of around 10/12 seconds before the memory location appears.
How were you running this script?
I used a Stream Deck button
How important is this issue to you?
5
Details
{ "inputExpected": "I currently have three presets I've set up within the Advanced Memory Locations Template. CLICK, NOISE and POP. Whenever I press these on my Stream Deck within big session they are very slow to load within Pro Tools. I have a lag of around 10/12 seconds.\n\nHowever, if I add a memory location manaully it's super fast. The problem does not persist in smaller sessions.\n\nThanks in advance\nPeter", "inputIsError": false, "inputWhatHappens": "When I press the button on Stream Deck to activate the macros, it's as if I haven't pressed anything. There's a delay of around 10/12 seconds before the memory location appears.", "inputHowRun": { "key": "-MpfwmPg-2Sb-HxHQAff", "title": "I used a Stream Deck button" }, "inputImportance": 5, "inputTitle": "Lag when pressing Stream Deck Advanced Locations" }
Source
const { cueText } = event.props;
const isMemLocWinOpened = sf.ui.proTools.getMenuItem('Window', 'Memory Locations').isMenuChecked
const memoryLocations = sf.proTools.memoryLocationsFetchFromGui().collection.list.filter(x => x.name.match(cueText))
const modifierState = event.keyboardState.asString
/**
* @param {object} obj
* @param {string} obj.name
*/
function createMemoryLocationsMarker({ name }) {
sf.ui.proTools.appActivateMainWindow();
const dlg = sf.ui.proTools.newMemoryLocationDialog;
if (!dlg.exists) {
sf.keyboard.press({ keys: "numpad enter" });
}
dlg.elementWaitFor();
dlg.radioButtons.whoseTitle.is("Marker").first.elementClick();
dlg.textFields.allItems[1].elementSetTextFieldWithAreaValue({
value: name,
});
dlg.buttons.whoseTitle.is("OK").first.elementClick();
dlg.elementWaitFor({ waitType: "Disappear", });
}
function paste(memoryLocations) {
sf.ui.proTools.memoryLocationsGoto({
memoryLocationNumber: memoryLocations.number
})
sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"] })
}
function clearMemoryLocations(name) {
// // Open mem loc win
sf.ui.proTools.memoryLocationsShowWindow()
// Get Memory Locations including...
const memoryLocations = sf.proTools.memoryLocationsFetch().collection['List'].filter(m => m.name.includes(name))
// Clear found
memoryLocations.forEach(memLoc => {
sf.ui.proTools.memoryLocationsGoto({ memoryLocationNumber: memLoc.number })
sf.ui.proTools.memoryLocationsWindow.popupButtons.first.popupMenuSelect({ menuPath: ['Clear*'], useWildcards: true });
});
///alert(`Cleared All Memory Locations Names Including: \n\n - ${name} -`)
};
function goToNextMatchedMemoryLocation(locationName) {
let currentTimecode = sf.ui.proTools.getCurrentTimecode().stringValue;
// if main counter is bars beats, remove last three digits, since memory locations list ignores them
currentTimecode.match(/\|/) ? currentTimecode = currentTimecode.slice(0, -3) : null;
let cleanMainCounter = Number(currentTimecode.replace(/[^0-9]/g, '').trim());
const memoryLocations = sf.proTools.memoryLocationsFetch().collection["list"].filter(x =>
Number(x.mainCounterValue.replace(/[^0-9]/g, '').trim()) > cleanMainCounter && x.name.match(locationName)
);
try {
sf.ui.proTools.memoryLocationsGoto({ memoryLocationNumber: memoryLocations[0].number });
} catch (err) {
log(`End of location markers containing:\n${locationName}`);
}
}
function getPreviousMatchedMemoryLocation(locationName) {
let mainCounter = sf.ui.proTools.getCurrentTimecode().stringValue
// if main counter is bars beats, remove last three digits, since memory locations list ignores them
mainCounter.match(/\|/) ? mainCounter = mainCounter.slice(0, -3) : null
let cleanMainCounter = Number(mainCounter.replace(/[^0-9]/g, '').trim())
const memoryLocations = sf.proTools.memoryLocationsFetch().collection["list"].filter(x =>
Number(x.mainCounterValue.replace(/[^0-9]/g, '').trim()) < cleanMainCounter &&
x.name.match(locationName)
).reverse();
try {
sf.ui.proTools.memoryLocationsGoto({
memoryLocationNumber: memoryLocations[0].number
});
} catch (err) { log(`End of location markers containing:\n${locationName}`) }
}
/** Counts the amount of times this function is called during a fixed amount of time
* and passes that value to a callback from which different actions can take place.
* @param {object} args
* @param {string} args.name - Name for this instance.
* @param {number} args.waitTime - Amount of time to wait in milliseconds.
* @param {function} args.action - Callback to execute when the waitTime is over. Counter value will be passed as an argument.
*/
function actionCounter({ name, waitTime, action }) {
let actionCounter;
if (!globalState.actionCounter) globalState.actionCounter = {};
actionCounter = globalState.actionCounter;
if (!actionCounter[name]) {
actionCounter[name] = {
dateMs: (new Date).valueOf(),
i: 1
};
} else {
actionCounter[name].i++
return;
}
sf.engine.runInBackground(() => {
sf.wait({ intervalMs: waitTime, executionMode: "Background" });
try {
action(actionCounter[name].i);
} finally {
delete globalState.actionCounter
}
});
}
function main() {
if (globalState.toggleCreateOrGoTo == undefined || globalState.toggleCreateOrGoTo === true) {
switch (modifierState) {
case "cmd":
memoryLocations.forEach(paste)
break
case "":
createMemoryLocationsMarker({
name: cueText,
});
break
case "shift":
clearMemoryLocations(cueText)
break
};
}
if (globalState.toggleCreateOrGoTo === false) {
switch (modifierState) {
case "cmd":
memoryLocations.forEach(paste)
break
case "":
actionCounter({
name: 'memoryLocaitonFowardorBackwards',
waitTime: 500,
action: i => {
switch (i) {
case 1:
goToNextMatchedMemoryLocation(cueText)
break;
case 2:
getPreviousMatchedMemoryLocation(cueText)
break;
}
}
});
break
case "shift":
clearMemoryLocations(cueText)
break
};
}
// Set initial state of Mem Loc Win
if (!isMemLocWinOpened) {
sf.ui.proTools.menuClick({ menuPath: ['Window', 'Memory Locations'], targetValue: "Disable" })
};
}
main()
Links
User UID: Xm0t8L8vbddwUSfY4G9a7IsOZqt2
Feedback Key: sffeedback:Xm0t8L8vbddwUSfY4G9a7IsOZqt2:-N0e3kwp7dhu2U_q8JiZ
- SSoundFlow Bot @soundflowbot
Thanks for posting a question or an issue related to the 'Marker CUE Button Creator' package.
This package is made by @Owen_Granich_Young. We're auto-tagging them here so that they will hopefully be able to help you. - In reply toPeter_Gallacher⬆:Kitch Membery @Kitch2022-05-03 01:50:08.771Z2022-05-03 16:43:22.095Z
@Peter_Gallacher & @Owen_Granich_Young...
OK... So this is untested, but I finally got around to doing a bit of a refactor;
- I Removed multiple times that the Memory Locations window was being scraped (as it only needs to happen once).
- Removed a duplicate way the Memory locations were being scraped (there were two different methods being used).
- I combined the navigate to markers functions as there was a bunch of duplicate code.
- I renamed some of the functions and variables as their names did not match what they were doing.
It's not perfect but hopefully it will speed the script up on large sessions.
Let me know how it goes. Or if it even works still hahahhaha!?!?!?!??!!
Be sure to save your original script before overwriting just in case :-)
Here it is;
const { cueText } = event.props; const isMemLocWinOpened = sf.ui.proTools.getMenuItem('Window', 'Memory Locations').isMenuChecked; const memoryLocations = sf.proTools.memoryLocationsFetch().collection['List']; const matchingMemoryLocations = memoryLocations.filter(ml => ml.name === (cueText)); const modifierState = event.keyboardState.asString; /** * @param {object} obj * @param {string} obj.name */ function createMemoryLocationsMarker({ name }) { sf.ui.proTools.appActivateMainWindow(); const dlg = sf.ui.proTools.newMemoryLocationDialog; if (!dlg.exists) { sf.keyboard.press({ keys: "numpad enter" }); } dlg.elementWaitFor(); dlg.radioButtons.whoseTitle.is("Marker").first.elementClick(); dlg.textFields.allItems[1].elementSetTextFieldWithAreaValue({ value: name, }); dlg.buttons.whoseTitle.is("OK").first.elementClick(); dlg.elementWaitFor({ waitType: "Disappear", }); } function pasteAtMemoryLocation(memoryLocation) { sf.ui.proTools.memoryLocationsGoto({ memoryLocationNumber: memoryLocation.number, }); sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"], }); } function clearMemoryLocations() { sf.ui.proTools.memoryLocationsShowWindow(); memoryLocations.forEach(memLoc => { sf.ui.proTools.memoryLocationsGoto({ memoryLocationNumber: memLoc.number, }); sf.ui.proTools.memoryLocationsWindow.popupButtons.first.popupMenuSelect({ menuPath: ['Clear*'], useWildcards: true, }); }); }; /** * @param {object} obj * @param {string} obj.locationName * @param {string} obj.direction */ function goToMatchedMemoryLocation({ locationName, direction }) { let currentTimecode = sf.ui.proTools.getCurrentTimecode().stringValue; //If main counter is bars beats, remove last three digits, since memory locations list ignores them currentTimecode.match(/\|/) ? currentTimecode = currentTimecode.slice(0, -3) : null; let cleanMainCounter = Number(currentTimecode.replace(/[^0-9]/g, '').trim()); let targetMemoryLocation; if (direction === "next") { targetMemoryLocation = matchingMemoryLocations.filter(x => Number(x.mainCounterValue.replace(/[^0-9]/g, '').trim()) > cleanMainCounter )[0].number; } else if (direction === "previous") { targetMemoryLocation = matchingMemoryLocations.filter(x => Number(x.mainCounterValue.replace(/[^0-9]/g, '').trim()) < cleanMainCounter ).reverse()[0].number; } try { sf.ui.proTools.memoryLocationsGoto({ memoryLocationNumber: targetMemoryLocation, }); } catch (err) { log(`There are no "${direction}"" location markers containing:\n"${locationName}"`); } } /** Counts the amount of times this function is called during a fixed amount of time * and passes that value to a callback from which different actions can take place. * @param {object} args * @param {string} args.name - Name for this instance. * @param {number} args.waitTime - Amount of time to wait in milliseconds. * @param {function} args.action - Callback to execute when the waitTime is over. Counter value will be passed as an argument. */ function actionCounter({ name, waitTime, action }) { let actionCounter; if (!globalState.actionCounter) globalState.actionCounter = {}; actionCounter = globalState.actionCounter; if (!actionCounter[name]) { actionCounter[name] = { dateMs: (new Date).valueOf(), i: 1 }; } else { actionCounter[name].i++ return; } sf.engine.runInBackground(() => { sf.wait({ intervalMs: waitTime, executionMode: "Background" }); try { action(actionCounter[name].i); } finally { delete globalState.actionCounter; } }); } function main() { if (globalState.toggleCreateOrGoTo == undefined || globalState.toggleCreateOrGoTo === true) { switch (modifierState) { case "cmd": memoryLocations.forEach(pasteAtMemoryLocation); break case "": createMemoryLocationsMarker({ name: cueText, }); break case "shift": clearMemoryLocations(); break }; } if (globalState.toggleCreateOrGoTo === false) { switch (modifierState) { case "cmd": memoryLocations.forEach(pasteAtMemoryLocation); break case "": actionCounter({ name: 'memoryLocaitonFowardorBackwards', waitTime: 500, action: i => { switch (i) { case 1: goToMatchedMemoryLocation({ locationName: cueText, direction: "next" }); break; case 2: goToMatchedMemoryLocation({ locationName: cueText, direction: "previous" }); break; } } }); break case "shift": clearMemoryLocations(); break }; } // Set initial state of Mem Loc Win if (!isMemLocWinOpened) { sf.ui.proTools.menuClick({ menuPath: ['Window', 'Memory Locations'], targetValue: "Disable", }); }; } main();
UPDATED - ADDING MARKER NO-LONGER DELETES EXISTING MARKER
Rock on, champions!Peter Gallacher @Peter_Gallacher
WOW! Thanks for this @Kitch I will wait to hear back from @Owen_Granich_Young as he may want to update the app. Then I can update the app on my side once he's done it. Hopefully speak soon, Peter
- OOwen Granich-Young @Owen_Granich_Young
Kickass boss! I gotta do some ADR this morning but I'll update this afternoon.
You rock!
Hope to see you tomorrow at webinar.bests,
Owen
- In reply toKitch⬆:OOwen Granich-Young @Owen_Granich_Young
Uhoh @Kitch dropping a marker removes the previous one.... so only one of any type of marker can exist however you coded it. OH MY... in fact on closer testing ONLY ONE MARKER at all can exist...
Not sure what you did? I didn't get as far as checking the rest of the code as this part seems pretty function breaking.
More soon,
OwenKitch Membery @Kitch2022-05-03 16:46:10.174Z
Ahhh yeah, I was not expecting that behavior from the updated
createMemoryLocationsMarker
function (The original code for that was fine.).... It should be fixed/restored in the above post now.Rock on!
- OOwen Granich-Young @Owen_Granich_Young
Nice! I'll give it a spin and then upload when I'm home.
Peter Gallacher @Peter_Gallacher
Thanks @Owen_Granich_Young @Kitch I look forward to your updated tests Owen and an updated app in due course. Thanks again guys. Speak soon. Peter.
- In reply toKitch⬆:OOwen Granich-Young @Owen_Granich_Young
Ok so for some reason, the
Action Counter
Functionality is broken, and I can't figure it out. So no matter if you press twice or once when you're ingoTo
mode it only goes to the next location, not the previous. I swapped them as an experiment and Previous does work as well, so I'm not 100% what's wrong. @raphaelsepulveda this Action Counter Double tap is your script I've placed many places and it's always worked. Any idea why it might not like working in this script?Sadly my one ADR session today is at 11am so I'll miss webinar today @Kitch
more soon,
Owen- OOwen Granich-Young @Owen_Granich_Young
For reference Action Counter works perfectly well in this script.
function goToNextMatchedMemoryLocation(locationName) { let currentTimecode = sf.ui.proTools.getCurrentTimecode().stringValue; // if main counter is bars beats, remove last three digits, since memory locations list ignores them currentTimecode.match(/\|/) ? currentTimecode = currentTimecode.slice(0, -3) : null; let cleanMainCounter = Number(currentTimecode.replace(/[^0-9]/g, '').trim()); const memoryLocations = sf.proTools.memoryLocationsFetch().collection["list"].filter(x => Number(x.mainCounterValue.replace(/[^0-9]/g, '').trim()) > cleanMainCounter && x.name.match(locationName) ); try { sf.ui.proTools.memoryLocationsGoto({ memoryLocationNumber: memoryLocations[0].number }); } catch (err) { log(`End of location markers containing:\n${locationName}`); } } function getPreviousMatchedMemoryLocation(locationName) { let mainCounter = sf.ui.proTools.getCurrentTimecode().stringValue // if main counter is bars beats, remove last three digits, since memory locations list ignores them mainCounter.match(/\|/) ? mainCounter = mainCounter.slice(0, -3) : null let cleanMainCounter = Number(mainCounter.replace(/[^0-9]/g, '').trim()) const memoryLocations = sf.proTools.memoryLocationsFetch().collection["list"].filter(x => Number(x.mainCounterValue.replace(/[^0-9]/g, '').trim()) < cleanMainCounter && x.name.match(locationName) ).reverse(); try { sf.ui.proTools.memoryLocationsGoto({ memoryLocationNumber: memoryLocations[0].number }); } catch (err) { log(`End of location markers containing:\n${locationName}`) } } /** Counts the amount of times this function is called during a fixed amount of time * and passes that value to a callback from which different actions can take place. * @param {object} args * @param {string} args.name - Name for this instance. * @param {number} args.waitTime - Amount of time to wait in milliseconds. * @param {function} args.action - Callback to execute when the waitTime is over. Counter value will be passed as an argument. */ function actionCounter({ name, waitTime, action }) { let actionCounter; if (!globalState.actionCounter) globalState.actionCounter = {}; actionCounter = globalState.actionCounter; if (!actionCounter[name]) { actionCounter[name] = { dateMs: (new Date).valueOf(), i: 1 }; } else { actionCounter[name].i++ return; } sf.engine.runInBackground(() => { sf.wait({ intervalMs: waitTime, executionMode: "Background" }); try { action(actionCounter[name].i); } finally { delete globalState.actionCounter } }); } function main() { //Activate Pro Tools Main Window sf.ui.proTools.appActivateMainWindow(); //Get Control Modifier state const ctrlIsEnabled = event.keyboardState.hasControl; if (globalState.markerName == undefined || ctrlIsEnabled) { //Retrieve memory locations let memoryLocations = sf.proTools.memoryLocationsFetch().collection['List']; let memoryLocationNames = memoryLocations.map(ml => ml["Name"]); //Filter out Memory location name duplicates let uniqueMemoryLocationNames = [...new Set(memoryLocationNames)]; //Popup Search let targetMemoryLocation = sf.interaction.popupSearch({ items: uniqueMemoryLocationNames.map(name => ({ name: name })), }).item.name sf.ui.proTools.appActivateMainWindow(); //Set the globalState marker name globalState.markerName = targetMemoryLocation; } else { actionCounter({ name: 'memoryLocaitonFowardorBackwards', waitTime: 500, action: i => { switch (i) { case 1: goToNextMatchedMemoryLocation(globalState.markerName) break; case 2: getPreviousMatchedMemoryLocation(globalState.markerName) break; } } }); } } main();
- In reply toOwen_Granich_Young⬆:
Kitch Membery @Kitch2022-05-04 16:17:33.624Z
I'll take a look when I get a chance... If it was working before then IT's probably something I've done.
Can you note down the rules to the functionality, so I can check it..
ie;
When I hold down "Command" I want it to do this...
When I hold down "Shift" I want it to do this...
When I hold down no modifiers I want it to do this...
When I hold down "Command" and trigger twice within the 500ms I want it to do this...
When I hold down "Shift" and trigger twice within the 500ms I want it to do this...
When I hold down no modifiers and trigger twice within the 500ms I want it to do this...Thanks :-)
Rock on.- OOwen Granich-Young @Owen_Granich_Young
In Create Global State (all working as intended currently):
No Modifiers = Create Memory location withcueText
(working as intended)
Hold Shift = Remove Memory Locations withcueText
(working as intended)
Hold Cmd = Paste Clipboard to Memory Locations withcueText
(working as intended)In GoTo Global State
No Modifiers 1 press within 500ms = Go to next Memory location withcueText
No Modifiers 2 press within 500ms = Go to previous Memory location withcueText
(This currently only does the 1 press no matter what. I flipped them and both previous and next you have scripted do work correctly)Hold Shift = Remove Memory Locations with
cueText
(working as intended)
Hold Cmd = Paste Clipboard to Memory Locations withcueText
(working as intended)Bests,
OwenKitch Membery @Kitch2022-05-05 21:32:17.185Z
So... I've modified the main function to simplify the modifier/mode combinations. (4 combinations in total)
I also realized that fetching the Memory locations was closing the Memory Locations window by default, which I believe may have been causing the issue you are experiencing.const { cueText } = event.props; const isMemLocWinOpened = sf.ui.proTools.invalidate().memoryLocationsWindow.exists; const memoryLocations = sf.proTools.memoryLocationsFetch({ restoreWindowOpenState: false }).collection['List']; const matchingMemoryLocations = memoryLocations.filter(ml => ml.name === (cueText)); /** * @param {object} obj * @param {string} obj.name */ function createMemoryLocationsMarker({ name }) { sf.ui.proTools.appActivateMainWindow(); const dlg = sf.ui.proTools.newMemoryLocationDialog; if (!dlg.exists) { sf.keyboard.press({ keys: "numpad enter" }); } dlg.elementWaitFor(); dlg.radioButtons.whoseTitle.is("Marker").first.elementClick(); dlg.textFields.allItems[1].elementSetTextFieldWithAreaValue({ value: name, }); dlg.buttons.whoseTitle.is("OK").first.elementClick(); dlg.elementWaitFor({ waitType: "Disappear", }); } function pasteAtMemoryLocation(memoryLocation) { sf.ui.proTools.memoryLocationsGoto({ memoryLocationNumber: memoryLocation.number, }); sf.ui.proTools.menuClick({ menuPath: ["Edit", "Paste"], }); } function clearMemoryLocations() { sf.ui.proTools.memoryLocationsShowWindow(); memoryLocations.forEach(memLoc => { sf.ui.proTools.memoryLocationsGoto({ memoryLocationNumber: memLoc.number, }); sf.ui.proTools.memoryLocationsWindow.popupButtons.first.popupMenuSelect({ menuPath: ['Clear*'], useWildcards: true, }); }); }; /** * @param {object} obj * @param {string} obj.locationName * @param {string} obj.direction */ function goToMatchedMemoryLocation({ locationName, direction }) { let currentTimecode = sf.ui.proTools.getCurrentTimecode().stringValue; //If main counter is bars beats, remove last three digits, since memory locations list ignores them currentTimecode.match(/\|/) ? currentTimecode = currentTimecode.slice(0, -3) : null; let cleanMainCounter = Number(currentTimecode.replace(/[^0-9]/g, '').trim()); let targetMemoryLocation; if (direction === "next") { targetMemoryLocation = matchingMemoryLocations.filter(x => Number(x.mainCounterValue.replace(/[^0-9]/g, '').trim()) > cleanMainCounter )[0].number; } else if (direction === "previous") { targetMemoryLocation = matchingMemoryLocations.filter(x => Number(x.mainCounterValue.replace(/[^0-9]/g, '').trim()) < cleanMainCounter ).reverse()[0].number; } try { sf.ui.proTools.memoryLocationsGoto({ memoryLocationNumber: targetMemoryLocation, }); } catch (err) { log(`There are no "${direction}"" location markers containing:\n"${locationName}"`); } } /** Counts the amount of times this function is called during a fixed amount of time * and passes that value to a callback from which different actions can take place. * @param {object} args * @param {string} args.name - Name for this instance. * @param {number} args.waitTime - Amount of time to wait in milliseconds. * @param {function} args.action - Callback to execute when the waitTime is over. Counter value will be passed as an argument. */ function actionCounter({ name, waitTime, action }) { let actionCounter; if (!globalState.actionCounter) globalState.actionCounter = {}; actionCounter = globalState.actionCounter; if (!actionCounter[name]) { actionCounter[name] = { dateMs: (new Date).valueOf(), i: 1 }; } else { actionCounter[name].i++ return; } sf.engine.runInBackground(() => { sf.wait({ intervalMs: waitTime, executionMode: "Background" }); try { action(actionCounter[name].i); } finally { delete globalState.actionCounter; } }); } function main() { if (!isMemLocWinOpened) { sf.ui.proTools.menuClick({ menuPath: ['Window', 'Memory Locations'], targetValue: "Enable", }); }; const modifierState = event.keyboardState.asString; const isCreateMode = globalState.toggleCreateOrGoTo === undefined || globalState.toggleCreateOrGoTo === true; const isGoto = globalState.toggleCreateOrGoTo !== undefined && globalState.toggleCreateOrGoTo === false; switch (true) { // Create mode with Command modifier case modifierState === "cmd": memoryLocations.forEach(pasteAtMemoryLocation); break // Create mode with Shift modifier case modifierState === "shift": clearMemoryLocations(); break // Create mode with no modifiers case isCreateMode && modifierState === "": createMemoryLocationsMarker({ name: cueText }); break // GotTo mode with no modifiers case isGoto && modifierState === "": actionCounter({ name: 'memoryLocaitonFowardorBackwards', waitTime: 500, action: i => { switch (i) { //Single press within Action Counter wait time case 1: goToMatchedMemoryLocation({ locationName: cueText, direction: "next" }); break; //Single press within Action Counter wait time case 2: goToMatchedMemoryLocation({ locationName: cueText, direction: "previous" }); break; } } }); break }; //Restore initial state of Memory Location window if (!isMemLocWinOpened) { sf.ui.proTools.menuClick({ menuPath: ['Window', 'Memory Locations'], targetValue: "Disable", }); }; } main();
Let me know how it runs for you.
Rock on!
- OOwen Granich-Young @Owen_Granich_Young
Works like Gangbusters!!! Package has been updated. You've done so much work man thank you.
Now that you've done so much work just take the package away from me and turn it into a dynamic deck like Christians ProTools Spotting :D
But really, thanks again, @Peter_Gallacher I hope this speeds it back up?
Lets us know.
Peter Gallacher @Peter_Gallacher
Hi @Owen_Granich_Young that's great news. Will you update the app so I can get the updated version? Or do I just add the code in manually? If so, just remind me of where it goes again.
- OOwen Granich-Young @Owen_Granich_Young
I've updated the package 👍🏼
Kitch Membery @Kitch2022-05-06 16:50:18.414Z
Fingers crossed it speeds things up!!!
Peter Gallacher @Peter_Gallacher
Hi @Kitch @Owen_Granich_Young It's like Superman coming back from the dead in Justice League. Well done Kitch, awesome work once again. have a fab weekend folks. https://www.youtube.com/watch?v=gHKe5pT9sqk
Kitch Membery @Kitch2022-05-06 17:16:25.326Z
Yesssss!!!! Woooo!!!
Glad it worked:-)
- OOwen Granich-Young @Owen_Granich_Young
Niiiiiiiice
- In reply toPeter_Gallacher⬆:Peter Gallacher @Peter_Gallacher
Hi @Owen_Granich_Young @Kitch since I updated to the latest PT in June, my memory locations don't seem to add the text I used as presets. I've updated the app, but still no luck. Is there something I need to change/update.
Thanks in advance
Peter- OOwen Granich-Young @Owen_Granich_Young
Hey Peter, 2023.6 introduced new memory locations and it broke everything... sorry I haven't updated or dug into updating the script for it.
Peter Gallacher @Peter_Gallacher
Bless ya, no problem. When you get time to open the hood, then loop me in. Happy to help where I can as well.
Hors Piste @Hors_Piste
I would LOVE to see this package updates... would save so much time here ! Just hit me if I can help in some ways !
- OOwen Granich-Young @Owen_Granich_Young
Now with SDK, better faster stronger.... I know a really long wait.