mirror of
https://github.com/cookiengineer/audacity
synced 2025-11-21 08:27:13 +01:00
Bug 2468 - Python scripting of Nyquist effects must set ALL parameters, or all parameters are ignored.
My code is for normal Nyquist effects. This fix also incorporates a fix from Leland for Nyquist Prompt. Thanks Leland.
This commit is contained in:
@@ -113,6 +113,7 @@ enum
|
|||||||
|
|
||||||
static const wxChar *KEY_Version = wxT("Version");
|
static const wxChar *KEY_Version = wxT("Version");
|
||||||
static const wxChar *KEY_Command = wxT("Command");
|
static const wxChar *KEY_Command = wxT("Command");
|
||||||
|
static const wxChar *KEY_Parameters = wxT("Parameters");
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@@ -323,6 +324,7 @@ bool NyquistEffect::DefineParams( ShuttleParams & S )
|
|||||||
{
|
{
|
||||||
S.Define( mInputCmd, KEY_Command, "" );
|
S.Define( mInputCmd, KEY_Command, "" );
|
||||||
S.Define( mVersion, KEY_Version, 3 );
|
S.Define( mVersion, KEY_Version, 3 );
|
||||||
|
S.Define( mParameters, KEY_Parameters, "" );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,18 +368,11 @@ bool NyquistEffect::DefineParams( ShuttleParams & S )
|
|||||||
|
|
||||||
bool NyquistEffect::GetAutomationParameters(CommandParameters & parms)
|
bool NyquistEffect::GetAutomationParameters(CommandParameters & parms)
|
||||||
{
|
{
|
||||||
if (IsBatchProcessing())
|
|
||||||
{
|
|
||||||
parms.Write(KEY_Command, mInputCmd);
|
|
||||||
parms.Write(KEY_Version, mVersion);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mIsPrompt)
|
if (mIsPrompt)
|
||||||
{
|
{
|
||||||
parms.Write(KEY_Command, mInputCmd);
|
parms.Write(KEY_Command, mInputCmd);
|
||||||
parms.Write(KEY_Version, mVersion);
|
parms.Write(KEY_Version, mVersion);
|
||||||
|
parms.Write(KEY_Parameters, mParameters);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -423,43 +418,85 @@ bool NyquistEffect::GetAutomationParameters(CommandParameters & parms)
|
|||||||
|
|
||||||
bool NyquistEffect::SetAutomationParameters(CommandParameters & parms)
|
bool NyquistEffect::SetAutomationParameters(CommandParameters & parms)
|
||||||
{
|
{
|
||||||
if (IsBatchProcessing())
|
|
||||||
{
|
|
||||||
parms.Read(KEY_Command, &mInputCmd, wxEmptyString);
|
|
||||||
parms.Read(KEY_Version, &mVersion, mVersion);
|
|
||||||
|
|
||||||
if (!mInputCmd.empty()) {
|
|
||||||
ParseCommand(mInputCmd);
|
|
||||||
}
|
|
||||||
mPromptType = mType;
|
|
||||||
mIsTool = (GetType() == EffectTypeTool);
|
|
||||||
mExternal = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mIsPrompt)
|
if (mIsPrompt)
|
||||||
{
|
{
|
||||||
parms.Read(KEY_Command, &mInputCmd, wxEmptyString);
|
parms.Read(KEY_Command, &mInputCmd, wxEmptyString);
|
||||||
parms.Read(KEY_Version, &mVersion, mVersion);
|
parms.Read(KEY_Version, &mVersion, mVersion);
|
||||||
|
parms.Read(KEY_Parameters, &mParameters, wxEmptyString);
|
||||||
|
|
||||||
if (!mInputCmd.empty()) {
|
if (!mInputCmd.empty())
|
||||||
|
{
|
||||||
ParseCommand(mInputCmd);
|
ParseCommand(mInputCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mParameters.empty())
|
||||||
|
{
|
||||||
|
parms.SetParameters(mParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsBatchProcessing())
|
||||||
|
{
|
||||||
mType = EffectTypeTool;
|
mType = EffectTypeTool;
|
||||||
|
}
|
||||||
|
|
||||||
mPromptType = mType;
|
mPromptType = mType;
|
||||||
mIsTool = true;
|
mIsTool = (mPromptType == EffectTypeTool);
|
||||||
mExternal = true;
|
mExternal = true;
|
||||||
|
|
||||||
|
if (!IsBatchProcessing())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constants to document what the true/false values mean.
|
||||||
|
const auto kTestOnly = true;
|
||||||
|
const auto kTestAndSet = false;
|
||||||
|
|
||||||
|
// badCount will encompass both actual bad values and missing values.
|
||||||
|
// We probably never actually have bad values when using the dialogs
|
||||||
|
// since the dialog validation will catch them.
|
||||||
|
int badCount;
|
||||||
|
// When batch processing, we just ignore missing/bad parameters.
|
||||||
|
// We'll end up using defaults in those cases.
|
||||||
|
if (!IsBatchProcessing()) {
|
||||||
|
badCount = SetLispVarsFromParameters(parms, kTestOnly);
|
||||||
|
if (badCount > 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
badCount = SetLispVarsFromParameters(parms, kTestAndSet);
|
||||||
|
// We never do anything with badCount here.
|
||||||
|
// It might be non zero, for missing parameters, and we allow that,
|
||||||
|
// and don't distinguish that from an out-of-range value.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets the lisp variables form the parameters.
|
||||||
|
// returns the number of bad settings.
|
||||||
|
// We can run this just testing for bad values, or actually setting when
|
||||||
|
// the values are good.
|
||||||
|
int NyquistEffect::SetLispVarsFromParameters(CommandParameters & parms, bool bTestOnly)
|
||||||
|
{
|
||||||
|
int badCount = 0;
|
||||||
// First pass verifies values
|
// First pass verifies values
|
||||||
for (size_t c = 0, cnt = mControls.size(); c < cnt; c++)
|
for (size_t c = 0, cnt = mControls.size(); c < cnt; c++)
|
||||||
{
|
{
|
||||||
NyqControl & ctrl = mControls[c];
|
NyqControl & ctrl = mControls[c];
|
||||||
bool good = false;
|
bool good = false;
|
||||||
|
|
||||||
|
// This GetCtrlValue code is preserved from former code,
|
||||||
|
// but probably is pointless. The value d isn't used later,
|
||||||
|
// and GetCtrlValue does not appear to have important needed
|
||||||
|
// side effects.
|
||||||
|
if (!bTestOnly) {
|
||||||
|
double d = ctrl.val;
|
||||||
|
if (d == UNINITIALIZED_CONTROL && ctrl.type != NYQ_CTRL_STRING)
|
||||||
|
{
|
||||||
|
d = GetCtrlValue(ctrl.valStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_FLOAT_TEXT ||
|
if (ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_FLOAT_TEXT ||
|
||||||
ctrl.type == NYQ_CTRL_TIME)
|
ctrl.type == NYQ_CTRL_TIME)
|
||||||
{
|
{
|
||||||
@@ -467,6 +504,8 @@ bool NyquistEffect::SetAutomationParameters(CommandParameters & parms)
|
|||||||
good = parms.Read(ctrl.var, &val) &&
|
good = parms.Read(ctrl.var, &val) &&
|
||||||
val >= ctrl.low &&
|
val >= ctrl.low &&
|
||||||
val <= ctrl.high;
|
val <= ctrl.high;
|
||||||
|
if (good && !bTestOnly)
|
||||||
|
ctrl.val = val;
|
||||||
}
|
}
|
||||||
else if (ctrl.type == NYQ_CTRL_INT || ctrl.type == NYQ_CTRL_INT_TEXT)
|
else if (ctrl.type == NYQ_CTRL_INT || ctrl.type == NYQ_CTRL_INT_TEXT)
|
||||||
{
|
{
|
||||||
@@ -474,6 +513,8 @@ bool NyquistEffect::SetAutomationParameters(CommandParameters & parms)
|
|||||||
good = parms.Read(ctrl.var, &val) &&
|
good = parms.Read(ctrl.var, &val) &&
|
||||||
val >= ctrl.low &&
|
val >= ctrl.low &&
|
||||||
val <= ctrl.high;
|
val <= ctrl.high;
|
||||||
|
if (good && !bTestOnly)
|
||||||
|
ctrl.val = (double)val;
|
||||||
}
|
}
|
||||||
else if (ctrl.type == NYQ_CTRL_CHOICE)
|
else if (ctrl.type == NYQ_CTRL_CHOICE)
|
||||||
{
|
{
|
||||||
@@ -482,66 +523,30 @@ bool NyquistEffect::SetAutomationParameters(CommandParameters & parms)
|
|||||||
good = parms.ReadEnum(ctrl.var, &val,
|
good = parms.ReadEnum(ctrl.var, &val,
|
||||||
ctrl.choices.data(), ctrl.choices.size()) &&
|
ctrl.choices.data(), ctrl.choices.size()) &&
|
||||||
val != wxNOT_FOUND;
|
val != wxNOT_FOUND;
|
||||||
|
if (good && !bTestOnly)
|
||||||
|
ctrl.val = (double)val;
|
||||||
}
|
}
|
||||||
else if (ctrl.type == NYQ_CTRL_STRING || ctrl.type == NYQ_CTRL_FILE)
|
else if (ctrl.type == NYQ_CTRL_STRING || ctrl.type == NYQ_CTRL_FILE)
|
||||||
{
|
{
|
||||||
wxString val;
|
wxString val;
|
||||||
good = parms.Read(ctrl.var, &val);
|
good = parms.Read(ctrl.var, &val);
|
||||||
|
if (good && !bTestOnly)
|
||||||
|
ctrl.valStr = val;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
else if (ctrl.type == NYQ_CTRL_TEXT)
|
else if (ctrl.type == NYQ_CTRL_TEXT)
|
||||||
{
|
{
|
||||||
// This "control" is just fixed text (nothing to save or restore),
|
// This "control" is just fixed text (nothing to save or restore),
|
||||||
// so control is always "good".
|
// Does not count for good/bad counting.
|
||||||
good = true;
|
good = true;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if (!good)
|
badCount += !good ? 1 : 0;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
return badCount;
|
||||||
|
|
||||||
// Second pass sets the variables
|
|
||||||
for (size_t c = 0, cnt = mControls.size(); c < cnt; c++)
|
|
||||||
{
|
|
||||||
NyqControl & ctrl = mControls[c];
|
|
||||||
|
|
||||||
double d = ctrl.val;
|
|
||||||
if (d == UNINITIALIZED_CONTROL && ctrl.type != NYQ_CTRL_STRING)
|
|
||||||
{
|
|
||||||
d = GetCtrlValue(ctrl.valStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctrl.type == NYQ_CTRL_FLOAT || ctrl.type == NYQ_CTRL_FLOAT_TEXT ||
|
|
||||||
ctrl.type == NYQ_CTRL_TIME)
|
|
||||||
{
|
|
||||||
parms.Read(ctrl.var, &ctrl.val);
|
|
||||||
}
|
|
||||||
else if (ctrl.type == NYQ_CTRL_INT || ctrl.type == NYQ_CTRL_INT_TEXT)
|
|
||||||
{
|
|
||||||
int val;
|
|
||||||
parms.Read(ctrl.var, &val);
|
|
||||||
ctrl.val = (double) val;
|
|
||||||
}
|
|
||||||
else if (ctrl.type == NYQ_CTRL_CHOICE)
|
|
||||||
{
|
|
||||||
int val {0};
|
|
||||||
// untranslated
|
|
||||||
parms.ReadEnum(ctrl.var, &val,
|
|
||||||
ctrl.choices.data(), ctrl.choices.size());
|
|
||||||
ctrl.val = (double) val;
|
|
||||||
}
|
|
||||||
else if (ctrl.type == NYQ_CTRL_STRING || ctrl.type == NYQ_CTRL_FILE)
|
|
||||||
{
|
|
||||||
parms.Read(ctrl.var, &ctrl.valStr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Effect Implementation
|
// Effect Implementation
|
||||||
|
|
||||||
bool NyquistEffect::Init()
|
bool NyquistEffect::Init()
|
||||||
{
|
{
|
||||||
// When Nyquist Prompt spawns an effect GUI, Init() is called for Nyquist Prompt,
|
// When Nyquist Prompt spawns an effect GUI, Init() is called for Nyquist Prompt,
|
||||||
@@ -622,7 +627,7 @@ bool NyquistEffect::CheckWhetherSkipEffect()
|
|||||||
{
|
{
|
||||||
// If we're a prompt and we have controls, then we've already processed
|
// If we're a prompt and we have controls, then we've already processed
|
||||||
// the audio, so skip further processing.
|
// the audio, so skip further processing.
|
||||||
return (mIsPrompt && mControls.size() > 0);
|
return (mIsPrompt && mControls.size() > 0 && !IsBatchProcessing());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RegisterFunctions();
|
static void RegisterFunctions();
|
||||||
@@ -1018,12 +1023,34 @@ bool NyquistEffect::ShowInterface(
|
|||||||
|
|
||||||
NyquistEffect effect(NYQUIST_WORKER_ID);
|
NyquistEffect effect(NYQUIST_WORKER_ID);
|
||||||
|
|
||||||
|
if (IsBatchProcessing())
|
||||||
|
{
|
||||||
|
effect.SetBatchProcessing(true);
|
||||||
|
effect.SetCommand(mInputCmd);
|
||||||
|
|
||||||
|
CommandParameters cp;
|
||||||
|
cp.SetParameters(mParameters);
|
||||||
|
effect.SetAutomationParameters(cp);
|
||||||
|
|
||||||
|
// Show the normal (prompt or effect) interface
|
||||||
|
res = effect.ShowInterface(parent, factory, forceModal);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
CommandParameters cp;
|
||||||
|
effect.GetAutomationParameters(cp);
|
||||||
|
cp.GetParameters(mParameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
effect.SetCommand(mInputCmd);
|
effect.SetCommand(mInputCmd);
|
||||||
effect.mDebug = (mUIResultID == eDebugID);
|
effect.mDebug = (mUIResultID == eDebugID);
|
||||||
bool result = Delegate(effect, parent, factory);
|
res = Delegate(effect, parent, factory);
|
||||||
mT0 = effect.mT0;
|
mT0 = effect.mT0;
|
||||||
mT1 = effect.mT1;
|
mT1 = effect.mT1;
|
||||||
return result;
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NyquistEffect::PopulateOrExchange(ShuttleGui & S)
|
void NyquistEffect::PopulateOrExchange(ShuttleGui & S)
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ public:
|
|||||||
bool DefineParams( ShuttleParams & S ) override;
|
bool DefineParams( ShuttleParams & S ) override;
|
||||||
bool GetAutomationParameters(CommandParameters & parms) override;
|
bool GetAutomationParameters(CommandParameters & parms) override;
|
||||||
bool SetAutomationParameters(CommandParameters & parms) override;
|
bool SetAutomationParameters(CommandParameters & parms) override;
|
||||||
|
int SetLispVarsFromParameters(CommandParameters & parms, bool bTestOnly);
|
||||||
|
|
||||||
// Effect implementation
|
// Effect implementation
|
||||||
|
|
||||||
@@ -221,6 +222,7 @@ private:
|
|||||||
bool mOK;
|
bool mOK;
|
||||||
TranslatableString mInitError;
|
TranslatableString mInitError;
|
||||||
wxString mInputCmd; // history: exactly what the user typed
|
wxString mInputCmd; // history: exactly what the user typed
|
||||||
|
wxString mParameters; // The parameters of to be fed to a nested prompt
|
||||||
wxString mCmd; // the command to be processed
|
wxString mCmd; // the command to be processed
|
||||||
TranslatableString mName; ///< Name of the Effect (untranslated)
|
TranslatableString mName; ///< Name of the Effect (untranslated)
|
||||||
TranslatableString mPromptName; // If a prompt, we need to remember original name.
|
TranslatableString mPromptName; // If a prompt, we need to remember original name.
|
||||||
|
|||||||
Reference in New Issue
Block a user