mirror of
https://github.com/cookiengineer/audacity
synced 2025-12-16 09:31:14 +01:00
Automation: AudacityCommand
This is a squash of 50 commits.
This merges the capabilities of BatchCommands and Effects using a new
AudacityCommand class. AudacityCommand provides one function to specify the
parameters, and then we leverage that one function in automation, whether by chains,
mod-script-pipe or (future) Nyquist.
- Now have AudacityCommand which is using the same mechanism as Effect
- Has configurable parameters
- Has data-entry GUI (built using shuttle GUI)
- Registers with PluginManager.
- Menu commands now provided in chains, and to python batch.
- Tested with Zoom Toggle.
- ShuttleParams now can set, get, set defaults, validate and specify
the parameters.
- Bugfix: Don't overwrite values with defaults first time out.
- Add DefineParams function for all built-in effects.
- Extend CommandContext to carry output channels for results.
We abuse EffectsManager. It handles both Effects and
AudacityCommands now. In time an Effect should become a special case of
AudacityCommand and we'll split and rename the EffectManager class.
- Don't use 'default' as a parameter name.
- Massive renaming for CommandDefinitionInterface
- EffectIdentInterface becomes EffectDefinitionInterface
- EffectAutomationParameters becomes CommandAutomationParameters
- PluginType is now a bit field.
This way we can search for related types at the same time.
- Most old batch commands made into AudacityCommands.
The ones that weren't are for a reason. They are used by mod-script-pipe
to carry commands and responses across from a non-GUI thread to the GUI
thread.
- Major tidy up of ScreenshotCommand
- Reworking of SelectCommand
- GetPreferenceCommand and SetPreferenceCommand
- GetTrackInfo and SetTrackInfo
- GetInfoCommand
- Help, Open, Save, Import and Export commands.
- Removed obsolete commands ExecMenu, GetProjectInfo and SetProjectInfo
which are now better handled by other commands.
- JSONify "GetInfo: Commands" output, i.e. commas in the right places.
- General work on better Doxygen.
- Lyrics -> LyricsPanel
- Meter -> MeterPanel
- Updated Linux makefile.
- Scripting commands added into Extra menu.
- Distinct names for previously duplicated find-clipping parameters.
- Fixed longstanding error with erroneous status field number which
previously caused an ASSERT in debug.
- Sensible formatting of numbers in Chains, 0.1 not 0.1000000000137
This commit is contained in:
committed by
Paul Licameli
parent
b7b01d48e0
commit
1c988b4e3a
@@ -11,7 +11,12 @@
|
||||
\file PluginManager.cpp
|
||||
\brief
|
||||
|
||||
*//*******************************************************************/
|
||||
************************************************************************//**
|
||||
\class PluginManager
|
||||
\brief PluginManager maintains a list of all plug ins. That covers modules,
|
||||
effects, generators, analysis-effects, commands. It also has functions
|
||||
for shared and private configs - which need to move out.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -952,7 +957,8 @@ void PluginRegistrationDialog::OnOK(wxCommandEvent & WXUNUSED(evt))
|
||||
mLongestPath + wxT("\n");
|
||||
|
||||
wxString msg;
|
||||
msg.Printf(_("Enabling effects:\n\n%s"), last3);
|
||||
|
||||
msg.Printf(_("Enabling effects or commands:\n\n%s"), last3);
|
||||
|
||||
// Make sure the progress dialog is deleted before we call EndModal() or
|
||||
// we will leave the project window in an unusable state on OSX.
|
||||
@@ -970,7 +976,7 @@ void PluginRegistrationDialog::OnOK(wxCommandEvent & WXUNUSED(evt))
|
||||
if (item.state == STATE_Enabled && item.plugs[0]->GetPluginType() == PluginTypeStub)
|
||||
{
|
||||
last3 = last3.AfterFirst(wxT('\n')) + item.path + wxT("\n");
|
||||
auto status = progress.Update(++i, enableCount, wxString::Format(_("Enabling effect:\n\n%s"), last3));
|
||||
auto status = progress.Update(++i, enableCount, wxString::Format(_("Enabling effect or command:\n\n%s"), last3));
|
||||
if (status == ProgressResult::Cancelled)
|
||||
{
|
||||
break;
|
||||
@@ -982,7 +988,7 @@ void PluginRegistrationDialog::OnOK(wxCommandEvent & WXUNUSED(evt))
|
||||
for (size_t j = 0, cnt = item.plugs.size(); j < cnt; j++)
|
||||
{
|
||||
wxString errMsg;
|
||||
if (mm.RegisterPlugin(item.plugs[j]->GetProviderID(), path,
|
||||
if (mm.RegisterEffectPlugin(item.plugs[j]->GetProviderID(), path,
|
||||
errMsg))
|
||||
{
|
||||
for (size_t j = 0, cnt = item.plugs.size(); j < cnt; j++)
|
||||
@@ -1000,7 +1006,7 @@ void PluginRegistrationDialog::OnOK(wxCommandEvent & WXUNUSED(evt))
|
||||
}
|
||||
if (!errMsgs.empty())
|
||||
AudacityMessageBox( wxString::Format(
|
||||
_("Effect at %s failed to register:\n%s"),
|
||||
_("Effect or Command at %s failed to register:\n%s"),
|
||||
path, errMsgs
|
||||
) );
|
||||
}
|
||||
@@ -1370,11 +1376,21 @@ void PluginDescriptor::SetImporterExtensions(const wxArrayString & extensions)
|
||||
// ============================================================================
|
||||
|
||||
const PluginID &PluginManagerInterface::DefaultRegistrationCallback(
|
||||
ModuleInterface *provider, EffectIdentInterface *pInterface )
|
||||
ModuleInterface *provider, CommandDefinitionInterface *pInterface )
|
||||
{
|
||||
EffectDefinitionInterface * pEInterface = dynamic_cast<EffectDefinitionInterface*>(pInterface);
|
||||
if( pEInterface )
|
||||
return PluginManager::Get().RegisterPlugin(provider, pEInterface, PluginTypeEffect);
|
||||
return PluginManager::Get().RegisterPlugin(provider, pInterface);
|
||||
}
|
||||
|
||||
const PluginID &PluginManagerInterface::GenericRegistrationCallback(
|
||||
ModuleInterface *provider, CommandDefinitionInterface *pInterface )
|
||||
{
|
||||
return PluginManager::Get().RegisterPlugin(provider, pInterface);
|
||||
}
|
||||
|
||||
|
||||
bool PluginManager::IsPluginRegistered(const wxString & path)
|
||||
{
|
||||
for (PluginMap::iterator iter = mPlugins.begin(); iter != mPlugins.end(); ++iter)
|
||||
@@ -1398,9 +1414,28 @@ const PluginID & PluginManager::RegisterPlugin(ModuleInterface *module)
|
||||
return plug.GetID();
|
||||
}
|
||||
|
||||
const PluginID & PluginManager::RegisterPlugin(ModuleInterface *provider, EffectIdentInterface *effect)
|
||||
const PluginID & PluginManager::RegisterPlugin(ModuleInterface *provider, CommandDefinitionInterface *command)
|
||||
{
|
||||
PluginDescriptor & plug = CreatePlugin(GetID(effect), effect, PluginTypeEffect);
|
||||
PluginDescriptor & plug = CreatePlugin(GetID(command), command, (PluginType)PluginTypeGeneric);
|
||||
|
||||
plug.SetProviderID(PluginManager::GetID(provider));
|
||||
|
||||
//plug.SetEffectType(effect->GetType());
|
||||
//plug.SetEffectFamily(effect->GetFamily());
|
||||
//plug.SetEffectInteractive(effect->IsInteractive());
|
||||
//plug.SetEffectDefault(effect->IsDefault());
|
||||
//plug.SetEffectRealtime(effect->SupportsRealtime());
|
||||
//plug.SetEffectAutomatable(effect->SupportsAutomation());
|
||||
|
||||
plug.SetEnabled(true);
|
||||
plug.SetValid(true);
|
||||
|
||||
return plug.GetID();
|
||||
}
|
||||
|
||||
const PluginID & PluginManager::RegisterPlugin(ModuleInterface *provider, EffectDefinitionInterface *effect, int type)
|
||||
{
|
||||
PluginDescriptor & plug = CreatePlugin(GetID(effect), effect, (PluginType)type);
|
||||
|
||||
plug.SetProviderID(PluginManager::GetID(provider));
|
||||
|
||||
@@ -1805,15 +1840,14 @@ bool PluginManager::DropFile(const wxString &fileName)
|
||||
std::vector<PluginID> ids;
|
||||
std::vector<wxString> names;
|
||||
nPlugIns = module->DiscoverPluginsAtPath(dstPath, errMsg,
|
||||
[&](ModuleInterface *provider, EffectIdentInterface *ident){
|
||||
[&](ModuleInterface *provider, CommandDefinitionInterface *ident){
|
||||
// Register as by default, but also collecting the PluginIDs
|
||||
// and names
|
||||
const auto &id =
|
||||
PluginManagerInterface::DefaultRegistrationCallback(
|
||||
const PluginID * id = &PluginManagerInterface::DefaultRegistrationCallback(
|
||||
provider, ident);
|
||||
ids.push_back(id);
|
||||
ids.push_back(*id);
|
||||
names.push_back( wxGetTranslation( ident->GetName() ) );
|
||||
return id;
|
||||
return *id;
|
||||
});
|
||||
if ( ! nPlugIns ) {
|
||||
// Unlikely after the dry run succeeded
|
||||
@@ -1877,6 +1911,7 @@ void PluginManager::Load()
|
||||
|
||||
// Now the rest
|
||||
LoadGroup(®istry, PluginTypeEffect);
|
||||
LoadGroup(®istry, PluginTypeGeneric );
|
||||
LoadGroup(®istry, PluginTypeExporter);
|
||||
LoadGroup(®istry, PluginTypeImporter);
|
||||
|
||||
@@ -2174,12 +2209,13 @@ void PluginManager::Save()
|
||||
// Save the individual groups
|
||||
SaveGroup(®istry, PluginTypeEffect);
|
||||
SaveGroup(®istry, PluginTypeExporter);
|
||||
SaveGroup(®istry, PluginTypeGeneric);
|
||||
SaveGroup(®istry, PluginTypeImporter);
|
||||
SaveGroup(®istry, PluginTypeStub);
|
||||
|
||||
// Not used by 2.1.1 or greater, but must save to allow users to switch between 2.1.0
|
||||
// and 2.1.1+. This should be removed after a few releases past 2.1.0.
|
||||
SaveGroup(®istry, PluginTypeNone);
|
||||
//SaveGroup(®istry, PluginTypeNone);
|
||||
|
||||
// And now the providers
|
||||
SaveGroup(®istry, PluginTypeModule);
|
||||
@@ -2377,9 +2413,9 @@ bool PluginManager::ShowManager(wxWindow *parent, EffectType type)
|
||||
|
||||
// Here solely for the purpose of Nyquist Workbench until
|
||||
// a better solution is devised.
|
||||
const PluginID & PluginManager::RegisterPlugin(EffectIdentInterface *effect)
|
||||
const PluginID & PluginManager::RegisterPlugin(EffectDefinitionInterface *effect, PluginType type)
|
||||
{
|
||||
PluginDescriptor & plug = CreatePlugin(GetID(effect), effect, PluginTypeEffect);
|
||||
PluginDescriptor & plug = CreatePlugin(GetID(effect), effect, type);
|
||||
|
||||
plug.SetEffectType(effect->GetType());
|
||||
plug.SetEffectFamilyId(effect->GetFamilyId());
|
||||
@@ -2433,40 +2469,40 @@ const PluginDescriptor *PluginManager::GetPlugin(const PluginID & ID)
|
||||
return &mPlugins[ID];
|
||||
}
|
||||
|
||||
const PluginDescriptor *PluginManager::GetFirstPlugin(PluginType type)
|
||||
const PluginDescriptor *PluginManager::GetFirstPlugin(int type)
|
||||
{
|
||||
for (mPluginsIter = mPlugins.begin(); mPluginsIter != mPlugins.end(); ++mPluginsIter)
|
||||
{
|
||||
PluginDescriptor & plug = mPluginsIter->second;
|
||||
bool familyEnabled = true;
|
||||
if (type == PluginTypeEffect)
|
||||
PluginType plugType = plug.GetPluginType();
|
||||
if( plug.IsValid() && plug.IsEnabled() && ((plugType & type) != 0))
|
||||
{
|
||||
// This preference may be written by EffectsPrefs
|
||||
gPrefs->Read(plug.GetEffectFamilyId() + wxT("/Enable"), &familyEnabled, true);
|
||||
}
|
||||
if (plug.IsValid() && plug.IsEnabled() && plug.GetPluginType() == type && familyEnabled)
|
||||
{
|
||||
return &mPluginsIter->second;
|
||||
bool familyEnabled = true;
|
||||
if( (plugType & PluginTypeEffect) != 0)
|
||||
// This preference may be written by EffectsPrefs
|
||||
gPrefs->Read(plug.GetEffectFamilyId() + wxT("/Enable"), &familyEnabled, true);
|
||||
if (familyEnabled)
|
||||
return &mPluginsIter->second;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const PluginDescriptor *PluginManager::GetNextPlugin(PluginType type)
|
||||
const PluginDescriptor *PluginManager::GetNextPlugin(int type)
|
||||
{
|
||||
while (++mPluginsIter != mPlugins.end())
|
||||
{
|
||||
PluginDescriptor & plug = mPluginsIter->second;
|
||||
bool familyEnabled = true;
|
||||
if (type == PluginTypeEffect)
|
||||
PluginType plugType = plug.GetPluginType();
|
||||
if( plug.IsValid() && plug.IsEnabled() && ((plugType & type) != 0))
|
||||
{
|
||||
// This preference may be written by EffectsPrefs
|
||||
gPrefs->Read(plug.GetEffectFamilyId() + wxT("/Enable"), &familyEnabled, true);
|
||||
}
|
||||
if (plug.IsValid() && plug.IsEnabled() && plug.GetPluginType() == type && familyEnabled)
|
||||
{
|
||||
return &mPluginsIter->second;
|
||||
bool familyEnabled = true;
|
||||
if( (plugType & PluginTypeEffect) != 0)
|
||||
// This preference may be written by EffectsPrefs
|
||||
gPrefs->Read(plug.GetEffectFamilyId() + wxT("/Enable"), &familyEnabled, true);
|
||||
if (familyEnabled)
|
||||
return &mPluginsIter->second;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2596,7 +2632,17 @@ PluginID PluginManager::GetID(ModuleInterface *module)
|
||||
module->GetPath());
|
||||
}
|
||||
|
||||
PluginID PluginManager::GetID(EffectIdentInterface *effect)
|
||||
PluginID PluginManager::GetID(CommandDefinitionInterface *command)
|
||||
{
|
||||
return wxString::Format(wxT("%s_%s_%s_%s_%s"),
|
||||
GetPluginTypeString(PluginTypeGeneric),
|
||||
wxEmptyString,
|
||||
command->GetVendor(),
|
||||
command->GetName(),
|
||||
command->GetPath());
|
||||
}
|
||||
|
||||
PluginID PluginManager::GetID(EffectDefinitionInterface *effect)
|
||||
{
|
||||
return wxString::Format(wxT("%s_%s_%s_%s_%s"),
|
||||
GetPluginTypeString(PluginTypeEffect),
|
||||
@@ -2624,6 +2670,7 @@ wxString PluginManager::GetPluginTypeString(PluginType type)
|
||||
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
case PluginTypeNone:
|
||||
str = wxT("Placeholder");
|
||||
break;
|
||||
@@ -2633,6 +2680,9 @@ wxString PluginManager::GetPluginTypeString(PluginType type)
|
||||
case PluginTypeEffect:
|
||||
str = wxT("Effect");
|
||||
break;
|
||||
case PluginTypeGeneric:
|
||||
str = wxT("Generic");
|
||||
break;
|
||||
case PluginTypeExporter:
|
||||
str = wxT("Exporter");
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user