Hey SF.
As the title explains, I'm trying to create a macro that will open the "Elastic Properties" window of an Elastic Audio enabled clip, give a prompt asking the amount you want to change the pitch (semitone or cents), then changing it to that amount and then closing the "Elastic Properties" window.
Here is a video of how I was setting it up, sorry for the (vertical video):
https://drive.google.com/file/d/1FipyOb_ZgUr_swUJakRwuV1nU5Sg3AcR/view?usp=sharing
I got the idea from a video Chad posted a few days ago on your YouTube channel about opening the quantize window and setting the strength amount. A script for this is above my skill level, but I've converted it to a script and pasted below. Any help on this would be greatly appreciated!
const text = sf.interaction.popupText({
title: "Semitone pitch amount?",
}).text;
sf.ui.proTools.menuClick({
menuPath: ["Clip","Elastic Properties"],
});
sf.ui.proTools.windows.whoseTitle.is("Elastic Properties").first.elementWaitFor();
sf.ui.proTools.windows.whoseTitle.is("Elastic Properties").first.groups.whoseTitle.is(",j").first.textFields.whoseTitle.is("mCoarsePitchField").first.elementClick();
sf.ui.proTools.windows.whoseTitle.is("Elastic Properties").first.groups.whoseTitle.is(",j").first.textFields.whoseTitle.is("mCoarsePitchField").first.elementSetTextFieldWithAreaValue({
value: text,
useMouseKeyboard: true,
});
- Kitch Membery @Kitch2025-03-29 05:06:50.993Z
Try this @Bergatron_Music,
sf.ui.proTools.appActivateMainWindow(); const text = sf.interaction.popupText({ title: "Semitone pitch amount?", }).text; const elasticProperties = sf.ui.proTools.windows.whoseTitle.is("Elastic Properties").first; const wasElasticPropertiesWinVisible = elasticProperties.invalidate().exists; if (!wasElasticPropertiesWinVisible) { sf.ui.proTools.menuClick({ menuPath: ["Clip", "Elastic Properties"] }); } elasticProperties.elementWaitFor(); const mCoarsePitchField = elasticProperties.groups.whoseTitle.is(",j").first.textFields.whoseTitle.is("mCoarsePitchField").first; mCoarsePitchField.elementClick(); elasticProperties.elementRaise(); mCoarsePitchField.elementSetTextFieldWithAreaValue({ value: text, useMouseKeyboard: true, }); const operator = Number(text) > 0 ? "+" : Number(text) < 0 ? "" : ""; sf.waitFor({ callback: () => mCoarsePitchField.value.invalidate().value === `${operator}${text}`, timeout: 1000, }); sf.ui.proTools.appActivateMainWindow(); if (!wasElasticPropertiesWinVisible) { elasticProperties.windowClose(); }
Limited testing, but it should do the trick. :-)
Bergatron Music @Bergatron_Music
Hey Kitch.
Thanks for sending this! The script seems to be acting funny. Sometimes it enters the number, but it doesn't change the pitch. Here's a vid to show you what's happening:
https://drive.google.com/file/d/1uqKGyNH0nAI9-7zY7rjwr4OCj8Fy3e1a/view?usp=drive_linkMaybe its a ProTools glitch? You'll notice when I manually entered the Semitone that it didn't change...
System Info:
Mac OS 14.7.4
ProTools Ultimate 2024.10.2
SF v5 10.2Kitch Membery @Kitch2025-03-31 18:06:21.180Z
Ahhh, I was not testing it on real audio so I missed one line of code to press return once the value had been written to the text field. Untested, but try this updated script.
sf.ui.proTools.appActivateMainWindow(); const text = sf.interaction.popupText({ title: "Semitone pitch amount?", }).text; const elasticProperties = sf.ui.proTools.windows.whoseTitle.is("Elastic Properties").first; const wasElasticPropertiesWinVisible = elasticProperties.invalidate().exists; if (!wasElasticPropertiesWinVisible) { sf.ui.proTools.menuClick({ menuPath: ["Clip", "Elastic Properties"] }); } elasticProperties.elementWaitFor(); const mCoarsePitchField = elasticProperties.groups.whoseTitle.is(",j").first.textFields.whoseTitle.is("mCoarsePitchField").first; mCoarsePitchField.elementClick(); elasticProperties.elementRaise(); mCoarsePitchField.elementSetTextFieldWithAreaValue({ value: text, useMouseKeyboard: true, }); const operator = Number(text) > 0 ? "+" : Number(text) < 0 ? "" : ""; sf.waitFor({ callback: () => mCoarsePitchField.value.invalidate().value === `${operator}${text}`, timeout: 1000, }); sf.keyboard.press({ keys: "return" }); sf.wait({ intervalMs: 200 }); if (!wasElasticPropertiesWinVisible) { elasticProperties.windowClose(); }
Bergatron Music @Bergatron_Music
As always Kitch, you're the man! Works perfect. THANK YOU!
Kitch Membery @Kitch2025-03-31 18:10:43.138Z
Awesome! :-)
Bergatron Music @Bergatron_Music
Hey @Kitch
I tried to figure it out, but I'm stuck! How can I change this script so that I have a "Cents" option as well? Thank you in advance!
Bergatron Music @Bergatron_Music
I figured it out! I just needed to change every "CoarsePitchField" to "FinePitchField". Thanks to your latest Youtube vid, I was able to figure out what was missing by using the "pick" button. Look out, he's learning!
Here is the script if anyone needs it:
const text = sf.interaction.popupText({ title: "Cents pitch amount?", }).text; const elasticProperties = sf.ui.proTools.windows.whoseTitle.is("Elastic Properties").first; const wasElasticPropertiesWinVisible = elasticProperties.invalidate().exists; if (!wasElasticPropertiesWinVisible) { sf.ui.proTools.menuClick({ menuPath: ["Clip", "Elastic Properties"] }); } elasticProperties.elementWaitFor(); const mFinePitchField = elasticProperties.groups.whoseTitle.is(",j").first.textFields.whoseTitle.is("mFinePitchField").first; mFinePitchField.elementClick(); elasticProperties.elementRaise(); mFinePitchField.elementSetTextFieldWithAreaValue({ value: text, useMouseKeyboard: true, }); const operator = Number(text) > 0 ? "+" : Number(text) < 0 ? "" : ""; sf.waitFor({ callback: () => mFinePitchField.value.invalidate().value === `${operator}${text}`, timeout: 1000, }); sf.keyboard.press({ keys: "return" }); sf.wait({ intervalMs: 200 }); if (!wasElasticPropertiesWinVisible) { elasticProperties.windowClose(); }
Kitch Membery @Kitch2025-04-01 23:01:20.820Z
Nice!!!