Title
Three-Body Technology's Kirchhoff EQ: Curve Randomizer
What do you expect to happen when you run the script/macro?
There's a plug-in called the Kirchhoff EQ which has several different modeled curves that you can assign per band. I wanted to make something that could randomize the shapes of the EQ bands I used. Each instance of the Kirchhoff EQ is instantiated with my user default preset. This preset consists of 12 bands -- two filters (inactive by default), two shelves (active by default) and eight bells (active by default). I have managed to make great progress with this idea. The script can already establish which bands have been moved, what the shape of that band is and what corresponding shapes exist that i can choose from at random. I don't get any errors when running the script however it is not function as intended. I believe this may simply be a result of trying to change parameter values too quickly. Currently I am using elementClick({ actionName: AXIncrement )} and the corresponding Decrement to adjust for the delta. Any help would be amazing. It would be really handy to see if broader Qs or slightly different curves could be better.
Are you seeing an error?
What happens when you run this script?
The parameter changes but incorrectly
How were you running this script?
I used a Stream Deck button
How important is this issue to you?
5
Details
{ "inputExpected": "There's a plug-in called the Kirchhoff EQ which has several different modeled curves that you can assign per band. I wanted to make something that could randomize the shapes of the EQ bands I used. Each instance of the Kirchhoff EQ is instantiated with my user default preset. This preset consists of 12 bands -- two filters (inactive by default), two shelves (active by default) and eight bells (active by default). I have managed to make great progress with this idea. The script can already establish which bands have been moved, what the shape of that band is and what corresponding shapes exist that i can choose from at random. I don't get any errors when running the script however it is not function as intended. I believe this may simply be a result of trying to change parameter values too quickly. Currently I am using elementClick({ actionName: AXIncrement )} and the corresponding Decrement to adjust for the delta. Any help would be amazing. It would be really handy to see if broader Qs or slightly different curves could be better.", "inputIsError": false, "inputWhatHappens": "The parameter changes but incorrectly", "inputHowRun": { "key": "-MpfwmPg-2Sb-HxHQAff", "title": "I used a Stream Deck button" }, "inputImportance": 5, "inputTitle": "Three-Body Technology's Kirchhoff EQ: Curve Randomizer" }
Source
function getUsedEqBands(kirchhoffEq, allEqBands) {
let enabledBands = []
for (let i = 0; i < allEqBands.length; i++) {
let bandEnabled = kirchhoffEq.sliders.whoseTitle.is(`Band${allEqBands[i]} Enabled`).first.value.invalidate().intValue;
// 0.03 dB = +1 in intValue. 0 dB = 1024 intValue
if (bandEnabled === 1) {
enabledBands.push(allEqBands[i])
}
}
let usedEqBands = []
for (let i = 0; i < enabledBands.length; i++) {
let eqBandType = kirchhoffEq.sliders.whoseTitle.is(`Band${enabledBands[i]} Type`).first;
let eqBandTypeIntValue = eqBandType.value.invalidate().intValue
// Band# Type intValues:
// High Pass Filter: Default - 1, Type E - 11, Type G - 19, British N - 25, Vintage Tube - 32
// Low Pass Filter: Default - 0, Type E - 18, Type G - 24, Vintage Tube - 33
let eqBandGain = kirchhoffEq.sliders.whoseTitle.is(`Band${enabledBands[i]} Gain`).first;
let eqBandGainIntValue = eqBandGain.value.invalidate().intValue;
// 0.03 dB = +1 in intValue of 1024
if ([0, 1, 11, 18, 19, 24, 25, 32, 33].indexOf(eqBandTypeIntValue) > -1 || eqBandGainIntValue !== 1024) {
usedEqBands.push(enabledBands[i])
}
}
return usedEqBands
}
////////////////////////////////////////////////////////////////////////////////////////////////////
function main() {
sf.ui.proTools.appActivateMainWindow();
sf.ui.proTools.mainWindow.invalidate();
const kirchhoffEq = sf.ui.proTools.windows.whoseTitle.is('Plug-in: TBTECH Kirchhoff-EQ').first.groups.whoseTitle.is('FXTDMEditView').first;
let allEqBands = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
let usedEqBands = getUsedEqBands(kirchhoffEq, allEqBands);
for (let i = 0; i < usedEqBands.length; i++) {
let eqBandType = kirchhoffEq.sliders.whoseTitle.is(`Band${usedEqBands[i]} Type`).first
let eqBandTypeIntValue = eqBandType.value.invalidate().intValue
let lowShelfTypesList = [4, 12, 20, 26, 29, 34, 39]
let highShelfTypesList = [5, 17, 23, 28, 31, 40, 46]
let bellTypesList = [3, 13, 14, 15, 16, 21, 22, 27, 30, 37, 38, 45]
// Band# Type intValues:
// Low Shelves: Default - 4, Type E - 12, Type G - 20, British N - 26, EQ 250 - 29, Vintage Tube - 34, Tone Stack - 39
// High Shelves: Default - 5, Type E - 17, Type G - 23, British N - 28, EQ 250 - 31, Vintage Tube (attn) - 36 DON'T INCLUDE, Tone Stack - 40, Blue - 46
// Bells:
//////// Default - 3,
//////// Type E Low - 13, Type E Low Mid - 14, Type E High Mid - 15, Type E High - 16
//////// Type G Low Mid - 21, Type G High Mid - 22
//////// British N - 27
//////// EQ 250 - 30
//////// Vintage Tube Boost - 35 DON'T INCLUDE, Vintage Tube Low Mid - 37, Vintage Tube High Mid - 38
//////// Blue Low - 45
if (lowShelfTypesList.indexOf(eqBandTypeIntValue) > -1) {
let shelfType = lowShelfTypesList[(Math.random() * 6).toFixed(0)]
let delta = eqBandTypeIntValue - shelfType
log(`Band: ${usedEqBands[i]}, Random Shape: lowShelfTypesList[${shelfType}], Delta: ${delta}`);
if (delta > 0) {
for (let i = 0; i < delta; i++) {
eqBandType.elementClick({ actionName: 'AXIncrement' });
}
} else if (delta < 0) {
for (let i = 0; i < Math.abs(delta); i++) {
eqBandType.elementClick({ actionName: 'AXDecrement' });
}
}
}
if (highShelfTypesList.indexOf(eqBandTypeIntValue) > -1) {
let shelfType = highShelfTypesList[(Math.random() * 6).toFixed(0)]
let delta = eqBandTypeIntValue - shelfType
log(`Band: ${usedEqBands[i]}, Random Shape: highShelfTypesList[${shelfType}], Delta: ${delta}`);
if (delta > 0) {
for (let i = 0; i < delta; i++) {
eqBandType.elementClick({ actionName: 'AXIncrement' });
}
} else if (delta < 0) {
for (let i = 0; i < Math.abs(delta); i++) {
eqBandType.elementClick({ actionName: 'AXDecrement' });
}
}
}
if (bellTypesList.indexOf(eqBandTypeIntValue) > -1) {
let bellType = bellTypesList[(Math.random() * 11).toFixed(0)]
let delta = eqBandTypeIntValue - bellType
log(`Band: ${usedEqBands[i]}, Random Shape: bellTypesList[${bellType}], Delta: ${delta}`);
if (delta > 0) {
for (let i = 0; i < delta; i++) {
eqBandType.elementClick({ actionName: 'AXIncrement' });
}
} else if (delta < 0) {
for (let i = 0; i < Math.abs(delta); i++) {
eqBandType.elementClick({ actionName: 'AXDecrement' });
}
}
}
}
}
main();
Links
User UID: EoVu20w2ZRTvmJvgozc57ZXuAhU2
Feedback Key: sffeedback:EoVu20w2ZRTvmJvgozc57ZXuAhU2:-NmdwgrK7Ayd4auJNewy
Feedback ZIP: hzofMdW0h0ggDPnOpMAKaguDttzjDq8w3kBIzw098EfDdcnjsqBuFbRqGjBfqWeE8DXH8wxJyRlY1UHx3eOAHlYTAu7b3B1XdtfhX7FHvHTvkB1nmJ8chD7+7Pw8pm2nI57tkIVY9/gIDGoovph9+xzUOEjvqoYmFIYFTO7CwQeTkExC51a8+iL5H6zqa/PmfnDtiNcOSCSXjkQhbsg1jXAzNAZQHKjAearIALZ45iOJWguhjIrorW/R/1rRf2OC6zhSFslGWGDcdNViumyvZs2mw6u61disfiR7HKt05VKeLyqjLyXqTJ9kYSVvQSUbFKRvKOO2gcNelOOBBNmeT3EsTzcjzBeDT8Ew1oNPRNc=
- Nathan Salefski @nathansalefski
Here's the aforementioned preset. It should be placed here before launching Pro Tools.
~/Documents/Pro Tools/Plug-In Settings/TBTECH Kirchhoff
https://www.dropbox.com/scl/fi/6x32ssl0wxegla6yvyf15/Default.tfx?rlkey=o605n9bmh7lgtomr9o7l97tad&dl=0 - In reply tonathansalefski⬆:Nathan Salefski @nathansalefski
I figured it out lol. I was calculating the delta incorrectly of course:
// Band# Type intValues: // High Pass Filter: Default - 1, Type E - 11, Type G - 19, British N - 25, Vintage Tube - 32 // Low Pass Filter: Default - 0, Type E - 18, Type G - 24, Vintage Tube - 33 // Low Shelves: Default - 4, Type E - 12, Type G - 20, British N - 26, EQ 250 - 29, Vintage Tube - 34, Tone Stack - 39 // High Shelves: Default - 5, Type E - 17, Type G - 23, British N - 28, EQ 250 - 31, Vintage Tube (attn) - 36 DON'T INCLUDE, Tone Stack - 40, Blue - 46 // Bells: //////// Default - 3, //////// Type E Low - 13, Type E Low Mid - 14, Type E High Mid - 15, Type E High - 16 //////// Type G Low Mid - 21, Type G High Mid - 22 //////// British N - 27 //////// EQ 250 - 30 //////// Vintage Tube Boost - 35 DON'T INCLUDE, Vintage Tube Low Mid - 37, Vintage Tube High Mid - 38 //////// Blue Low - 45 // All BANDS // 'Band1', 'Band2', 'Band3', 'Band4', 'Band5', 'Band6', // 'Band7', 'Band8', 'Band9', 'Band10', 'Band11', 'Band12', // 'Band13', 'Band14', 'Band15', 'Band16', 'Band17', 'Band18', // 'Band19', 'Band20', 'Band21', 'Band22', 'Band23', 'Band24', // 'Band25', 'Band26', 'Band27', 'Band28', 'Band29', 'Band30', // 'Band31', 'Band32' //////////////////////////////////////////////////////////////////////////////////////////////////// function getUsedEqBands(kirchhoffEq) { let allEqBands = ['Band1', 'Band2', 'Band3', 'Band4', 'Band5', 'Band6', 'Band7', 'Band8', 'Band9', 'Band10', 'Band11', 'Band12'] let enabledBands = allEqBands.filter((value) => { let bandEnabled = kirchhoffEq.sliders.whoseTitle.is(`${value} Enabled`).first.value.invalidate().intValue; if (bandEnabled === 1) { return value; } }); let usedEqBands = enabledBands.filter((value) => { let filterTypesList = [0, 1, 11, 18, 19, 24, 25, 32, 33] let eqBandTypeIntValue = kirchhoffEq.sliders.whoseTitle.is(`${value} Type`).first.value.invalidate().intValue let eqBandGainIntValue = kirchhoffEq.sliders.whoseTitle.is(`${value} Gain`).first.value.invalidate().intValue; if (filterTypesList.indexOf(eqBandTypeIntValue) > -1 || eqBandGainIntValue !== 1024) { return value; } }); return usedEqBands }; //////////////////////////////////////////////////////////////////////////////////////////////////// function main() { sf.ui.proTools.appActivateMainWindow(); sf.ui.proTools.mainWindow.invalidate(); const kirchhoffEq = sf.ui.proTools.windows.whoseTitle.is('Plug-in: TBTECH Kirchhoff-EQ').first.groups.whoseTitle.is('FXTDMEditView').first; let usedEqBands = getUsedEqBands(kirchhoffEq); for (let i = 0; i < usedEqBands.length; i++) { let eqBandType = kirchhoffEq.sliders.whoseTitle.is(`${usedEqBands[i]} Type`).first let eqBandTypeIntValue = eqBandType.value.invalidate().intValue let hpfTypesList = [1, 11, 19, 25, 32] let lowShelfTypesList = [4, 12, 20, 26, 29, 34, 39] let highShelfTypesList = [5, 17, 23, 28, 31, 40, 46] let lpfTypesList = [0, 18, 24, 33] let bellTypesList = [3, 13, 14, 15, 16, 21, 22, 27, 30, 37, 38, 45] let delta; if (hpfTypesList.indexOf(eqBandTypeIntValue) > -1) { let filterType = hpfTypesList[(Math.random() * 4).toFixed(0)] delta = filterType - eqBandTypeIntValue if (delta > 0) { for (let i = 0; i < delta; i++) { eqBandType.elementClick({ actionName: 'AXIncrement' }); } } else if (delta < 0) { for (let i = 0; i < Math.abs(delta); i++) { eqBandType.elementClick({ actionName: 'AXDecrement' }); } } } //////////////////////////////////////////////////////////////////////////////////////////////////// if (lowShelfTypesList.indexOf(eqBandTypeIntValue) > -1) { let shelfType = lowShelfTypesList[(Math.random() * 6).toFixed(0)] delta = shelfType - eqBandTypeIntValue if (delta > 0) { for (let i = 0; i < delta; i++) { eqBandType.elementClick({ actionName: 'AXIncrement' }); } } else if (delta < 0) { for (let i = 0; i < Math.abs(delta); i++) { eqBandType.elementClick({ actionName: 'AXDecrement' }); } } } //////////////////////////////////////////////////////////////////////////////////////////////////// if (highShelfTypesList.indexOf(eqBandTypeIntValue) > -1) { let shelfType = highShelfTypesList[(Math.random() * 6).toFixed(0)] delta = shelfType - eqBandTypeIntValue if (delta > 0) { for (let i = 0; i < delta; i++) { eqBandType.elementClick({ actionName: 'AXIncrement' }); } } else if (delta < 0) { for (let i = 0; i < Math.abs(delta); i++) { eqBandType.elementClick({ actionName: 'AXDecrement' }); } } } //////////////////////////////////////////////////////////////////////////////////////////////////// if (lpfTypesList.indexOf(eqBandTypeIntValue) > -1) { let filterType = lpfTypesList[(Math.random() * 3).toFixed(0)] delta = filterType - eqBandTypeIntValue if (delta > 0) { for (let i = 0; i < delta; i++) { eqBandType.elementClick({ actionName: 'AXIncrement' }); } } else if (delta < 0) { for (let i = 0; i < Math.abs(delta); i++) { eqBandType.elementClick({ actionName: 'AXDecrement' }); } } } //////////////////////////////////////////////////////////////////////////////////////////////////// if (bellTypesList.indexOf(eqBandTypeIntValue) > -1) { let bellType = bellTypesList[(Math.random() * 11).toFixed(0)] delta = bellType - eqBandTypeIntValue if (delta > 0) { for (let i = 0; i < delta; i++) { eqBandType.elementClick({ actionName: 'AXIncrement' }); } } else if (delta < 0) { for (let i = 0; i < Math.abs(delta); i++) { eqBandType.elementClick({ actionName: 'AXDecrement' }); } } } } } main();
Nathan Salefski @nathansalefski
We need an @avengers for all the geniuses on here. @Chad @Dustin_Harris @Chris_Shaw @raphaelsepulveda or @Kitch, completely at your leisure/if at all interested: this works great but is kinda slow. Are there ways you can see that this could be optimized? I believe that the
getUsedEqBands(kirchhoffEq);
function is what's slowing it down but without it, I feel like the large "for" loop in the main function would be incredibly inefficient.
Any ideas at all would be greatly appreciated. I hope you've had a Happy Holidays and have a great New Year!Kitch Membery @Kitch2023-12-29 21:00:04.176Z
Unfortunately, I don't have the "Kirchhoff EQ". So that counts me out.
- In reply tonathansalefski⬆:
Dustin Harris @Dustin_Harris
Is it slow -before- doing the AXIncrement/Decrement? because those actions are the things I'd assume are the slow ones (the band intValues themselves are not directly settable, so there is no choice there)
Dustin Harris @Dustin_Harris
at any rate, here's a quick refactor of
getUsedBands
, but I've modified it to use all bands, and there is a filter to limit the bands to below a certain number:/**@param {AxElement} kirchhoffEq */ function getUsedEqBands(kirchhoffEq) { const enabledBands = kirchhoffEq.children.whoseTitle.contains("Enabled") .filter(e => e.value.intValue === 1).map(b => b.title.value.split(" ")[0]); //end enabledBands const usedEqBands = enabledBands.filter((bandNumber) => { //enable limit if desired //if (Number(bandNumber.replace('Band', "")) > 12) return const filterTypesList = [0, 1, 11, 18, 19, 24, 25, 32, 33]; let eqBandTypeIntValue = kirchhoffEq.sliders.whoseTitle.is(`${bandNumber} Type`).first.value.invalidate().intValue; let eqBandGainIntValue = kirchhoffEq.sliders.whoseTitle.is(`${bandNumber} Gain`).first.value.invalidate().intValue; if (filterTypesList.includes(eqBandTypeIntValue) || eqBandGainIntValue !== 1024) { return bandNumber; } }); return usedEqBands };
Nathan Salefski @nathansalefski
Once the script is run there's probably about 3000ms before it starts to perform the
AXIncrement
orAXDecrement
actions. Plugging in this refactor has sped it up some. That rework of theenabledBands
is elegant. I didn't realize you could.filter
and.map
like thatDustin Harris @Dustin_Harris
changing the final
if
statement in the function to
if (eqBandGainIntValue !== 1024 ||filterTypesList.includes(eqBandTypeIntValue))
might be a little quicker too since it skips iterating over thefilterTypesList
array if it doesn't need to...Nathan Salefski @nathansalefski
Thanks man. I’ll try that out in the am and see how it goes. The
if (eqBandGainIntValue !== 1024 ||filterTypesList.includes(eqBandTypeIntValue))
is to determine if there’s filters so I think you’re right, only two filters would ever exist so it would likely speed it up tremendously- In reply toDustin_Harris⬆:
Nathan Salefski @nathansalefski
Hey Dustin,
I was playing around with the accessibility inspector and noticed that there is a fourth way to interact with some plugin parameters that I haven't seen before, it's 'pick'. Is that a way to set parameters directly using.elementClick({ actionName: 'AXPick' });
in some capacity?Dustin Harris @Dustin_Harris
Heyya Nathan! I’m not sure what AXPick does, I haven’t come across it yet… I’m away at the moment but I can mess around with it next week…
Nathan Salefski @nathansalefski
Thanks man