Allow chains to use current/factory presets/settings

Also gives builtin effects a mean to determine if batch processing
is active, IsBatchProcessing() returns true if so.
This commit is contained in:
Leland Lucius 2015-04-26 16:41:05 -05:00
parent 56e8f577bc
commit 4f4acffad1
16 changed files with 620 additions and 174 deletions

View File

@ -49,6 +49,7 @@ class AUDACITY_DLL_API ConfigClientInterface
public:
virtual ~ConfigClientInterface() {};
virtual bool HasSharedConfigGroup(const wxString & group) = 0;
virtual bool GetSharedConfigSubgroups(const wxString & group, wxArrayString & subgroups) = 0;
virtual bool GetSharedConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval) = 0;
@ -68,6 +69,7 @@ public:
virtual bool RemoveSharedConfigSubgroup(const wxString & group) = 0;
virtual bool RemoveSharedConfig(const wxString & group, const wxString & key) = 0;
virtual bool HasPrivateConfigGroup(const wxString & group) = 0;
virtual bool GetPrivateConfigSubgroups(const wxString & group, wxArrayString & subgroups) = 0;
virtual bool GetPrivateConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval) = 0;

View File

@ -62,6 +62,16 @@ public:
{
}
virtual bool HasGroup(const wxString & strName) const
{
return wxFileConfig::HasGroup(NormalizeName(strName));
}
virtual bool HasEntry(const wxString& strName) const
{
return wxFileConfig::HasEntry(NormalizeName(strName));
}
virtual bool DoReadString(const wxString & key, wxString *pStr) const
{
return wxFileConfig::DoReadString(NormalizeName(key), pStr);

View File

@ -45,17 +45,20 @@ selected command.
#define CommandsListID 7001
#define EditParamsButtonID 7002
#define UsePresetButtonID 7003
BEGIN_EVENT_TABLE(BatchCommandDialog, wxDialog)
EVT_BUTTON(wxID_OK, BatchCommandDialog::OnOk)
EVT_BUTTON(wxID_CANCEL, BatchCommandDialog::OnCancel)
EVT_BUTTON(EditParamsButtonID, BatchCommandDialog::OnEditParams)
EVT_LIST_ITEM_ACTIVATED(CommandsListID, BatchCommandDialog::OnItemSelected)
EVT_BUTTON(UsePresetButtonID, BatchCommandDialog::OnUsePreset)
EVT_LIST_ITEM_ACTIVATED(CommandsListID, BatchCommandDialog::OnItemSelected)
EVT_LIST_ITEM_SELECTED(CommandsListID, BatchCommandDialog::OnItemSelected)
END_EVENT_TABLE();
BatchCommandDialog::BatchCommandDialog(wxWindow * parent, wxWindowID id):
wxDialog(parent, id, _("Select Command"),
wxDefaultPosition, wxSize(250,200),
wxDefaultPosition, wxDefaultSize,
wxCAPTION | wxRESIZE_BORDER)
{
SetLabel(_("Select Command")); // Provide visual label
@ -75,13 +78,15 @@ void BatchCommandDialog::PopulateOrExchange(ShuttleGui &S)
{
S.StartVerticalLay(true);
{
S.StartMultiColumn(3, wxEXPAND);
S.StartMultiColumn(4, wxEXPAND);
{
S.SetStretchyCol(1);
mCommand = S.AddTextBox(_("&Command"), wxT(""), 20);
mCommand->SetEditable(false);
mEditParams = S.Id(EditParamsButtonID).AddButton(_("&Edit Parameters"));
mEditParams->Enable( false ); // disable button as box is empty
mEditParams->Enable(false); // disable button as box is empty
mUsePreset = S.Id(UsePresetButtonID).AddButton(_("&Use Preset"));
mUsePreset->Enable(false); // disable button as box is empty
}
S.EndMultiColumn();
@ -104,14 +109,10 @@ void BatchCommandDialog::PopulateOrExchange(ShuttleGui &S)
S.AddStandardButtons();
for(int i=0;i<99;i++)
{
mChoices->InsertItem( i, wxString::Format(wxT("Item%02i"),i));
}
PopulateCommandList();
SetSize(350, 400);
SetSizeHints(GetSize());
SetMinSize(wxSize(500, 400));
Fit();
Center();
}
@ -169,8 +170,12 @@ void BatchCommandDialog::OnItemSelected(wxListEvent &event)
mCommand->SetValue( command );
wxString params = BatchCommands::GetCurrentParamsFor( command );
mParameters->SetValue( params );
PluginID ID = EffectManager::Get().GetEffectByIdentifier( command );
mEditParams->Enable( !ID.empty() );
EffectManager & em = EffectManager::Get();
PluginID ID = em.GetEffectByIdentifier( command );
wxASSERT(!ID.IsEmpty());
mEditParams->Enable(true);
mUsePreset->Enable(em.HasPresets(ID));
}
void BatchCommandDialog::OnEditParams(wxCommandEvent & WXUNUSED(event))
@ -191,6 +196,19 @@ void BatchCommandDialog::OnEditParams(wxCommandEvent & WXUNUSED(event))
}
}
void BatchCommandDialog::OnUsePreset(wxCommandEvent & WXUNUSED(event))
{
wxString command = mCommand->GetValue();
wxString params = mParameters->GetValue();
wxString preset = BatchCommands::PromptForPresetFor(command, this);
if (!preset.IsEmpty())
{
mParameters->SetValue(preset);
mParameters->Refresh();
}
}
void BatchCommandDialog::SetCommandAndParams(const wxString &Command, const wxString &Params)
{
mCommand->SetValue( Command );

View File

@ -48,6 +48,7 @@ class BatchCommandDialog:public wxDialog {
void Populate();
void PopulateOrExchange(ShuttleGui &S);
void OnEditParams(wxCommandEvent &event);
void OnUsePreset(wxCommandEvent &event);
void OnChoice(wxCommandEvent &event);
void OnOk(wxCommandEvent &event);
void OnCancel(wxCommandEvent &event);
@ -58,6 +59,7 @@ class BatchCommandDialog:public wxDialog {
int GetSelectedItem();
wxButton *mEditParams;
wxButton *mUsePreset;
wxListCtrl *mChoices;
wxTextCtrl * mCommand;
wxTextCtrl * mParameters;

View File

@ -331,6 +331,18 @@ bool BatchCommands::PromptForParamsFor(wxString command, wxWindow *parent)
return EffectManager::Get().PromptUser(ID, parent);
}
wxString BatchCommands::PromptForPresetFor(wxString command, wxWindow *parent)
{
const PluginID & ID = EffectManager::Get().GetEffectByIdentifier(command);
if (ID.empty())
{
return wxEmptyString; // effect not found.
}
return EffectManager::Get().GetPreset(ID, parent);
}
double BatchCommands::GetEndTime()
{
AudacityProject *project = GetActiveProject();
@ -557,23 +569,19 @@ bool BatchCommands::ApplySpecialCommand(int WXUNUSED(iCommand), const wxString &
bool BatchCommands::SetCurrentParametersFor(const wxString & command, const wxString & params)
{
// transfer the parameters to the effect...
if( !params.IsEmpty() )
if (params.IsEmpty())
{
const PluginID & ID = EffectManager::Get().GetEffectByIdentifier(command);
if (ID.empty())
{
return false;
}
if (!EffectManager::Get().SetEffectParameters(ID, params))
{
wxMessageBox(
wxString::Format(
_("Could not set parameters of effect %s\n to %s."), command.c_str(),params.c_str() ));
return false;
}
return true;
}
return true;
// transfer the parameters to the effect...
const PluginID & ID = EffectManager::Get().GetEffectByIdentifier(command);
if (ID.empty())
{
return false;
}
return EffectManager::Get().SetEffectParameters(ID, params);
}
bool BatchCommands::ApplyEffectCommand(const PluginID & ID, const wxString & command, const wxString & params)
@ -594,7 +602,8 @@ bool BatchCommands::ApplyEffectCommand(const PluginID & ID, const wxString & com
// NOW actually apply the effect.
return project->OnEffect(ID, AudacityProject::OnEffectFlags::kConfigured |
AudacityProject::OnEffectFlags::kSkipState);
AudacityProject::OnEffectFlags::kSkipState |
AudacityProject::OnEffectFlags::kIsBatch );
}
bool BatchCommands::ApplyCommand(const wxString & command, const wxString & params)

View File

@ -43,6 +43,8 @@ class BatchCommands {
static bool PromptForParamsFor( wxString command, wxWindow *parent );
static wxString GetCurrentParamsFor( wxString command );
static bool SetCurrentParametersFor(const wxString & command, const wxString & params);
static wxString PromptForPresetFor( wxString command, wxWindow *parent );
static bool SetCurrentPresetFor(const wxString & command, const wxString & preset);
static wxArrayString GetAllCommands();
// These commands do depend on the command list.

View File

@ -3216,7 +3216,8 @@ bool AudacityProject::OnEffect(const PluginID & ID, int flags)
bool success = em.DoEffect(ID, this, mRate,
mTracks, mTrackFactory,
&mViewInfo.selectedRegion,
!(flags & OnEffectFlags::kConfigured));
(flags & OnEffectFlags::kConfigured) == 0,
(flags & OnEffectFlags::kIsBatch) != 0);
if (!success) {
if (newTrack) {

View File

@ -367,6 +367,8 @@ public:
static const int kConfigured = 0x01;
// Flag used to disable saving the state after processing.
static const int kSkipState = 0x02;
// Flag used to designate batch processing is active.
static const int kIsBatch = 0x04;
};
bool OnEffect(const PluginID & ID, int flags = OnEffectFlags::kNone);

View File

@ -1236,6 +1236,11 @@ void PluginManager::FindFilesInPathList(const wxString & pattern,
return;
}
bool PluginManager::HasSharedConfigGroup(const PluginID & ID, const wxString & group)
{
return HasGroup(SharedGroup(ID, group));
}
bool PluginManager::GetSharedConfigSubgroups(const PluginID & ID, const wxString & group, wxArrayString & subgroups)
{
return GetSubgroups(SharedGroup(ID, group), subgroups);
@ -1323,6 +1328,11 @@ bool PluginManager::RemoveSharedConfig(const PluginID & ID, const wxString & gro
return result;
}
bool PluginManager::HasPrivateConfigGroup(const PluginID & ID, const wxString & group)
{
return HasGroup(PrivateGroup(ID, group));
}
bool PluginManager::GetPrivateConfigSubgroups(const PluginID & ID, const wxString & group, wxArrayString & subgroups)
{
return GetSubgroups(PrivateGroup(ID, group), subgroups);
@ -2277,29 +2287,34 @@ wxFileConfig *PluginManager::GetSettings()
return mSettings;
}
bool PluginManager::HasGroup(const wxString & group)
{
return GetSettings()->HasGroup(group);
}
bool PluginManager::GetSubgroups(const wxString & group, wxArrayString & subgroups)
{
bool result = false;
if (!group.IsEmpty())
if (group.IsEmpty() || !HasGroup(group))
{
wxString name = wxEmptyString;
long index = 0;
wxString path = GetSettings()->GetPath();
GetSettings()->SetPath(group);
if (GetSettings()->GetFirstGroup(name, index))
{
do
{
subgroups.Add(name);
} while (GetSettings()->GetNextGroup(name, index));
}
GetSettings()->SetPath(path);
return false;
}
return result;
wxString path = GetSettings()->GetPath();
GetSettings()->SetPath(group);
wxString name = wxEmptyString;
long index = 0;
if (GetSettings()->GetFirstGroup(name, index))
{
do
{
subgroups.Add(name);
} while (GetSettings()->GetNextGroup(name, index));
}
GetSettings()->SetPath(path);
return true;
}
bool PluginManager::GetConfig(const wxString & key, int & value, int defval)

View File

@ -189,6 +189,7 @@ public:
wxArrayString & files,
bool directories = false);
virtual bool HasSharedConfigGroup(const PluginID & ID, const wxString & group);
virtual bool GetSharedConfigSubgroups(const PluginID & ID, const wxString & group, wxArrayString & subgroups);
virtual bool GetSharedConfig(const PluginID & ID, const wxString & group, const wxString & key, wxString & value, const wxString & defval = _T(""));
@ -208,6 +209,7 @@ public:
virtual bool RemoveSharedConfigSubgroup(const PluginID & ID, const wxString & group);
virtual bool RemoveSharedConfig(const PluginID & ID, const wxString & group, const wxString & key);
virtual bool HasPrivateConfigGroup(const PluginID & ID, const wxString & group);
virtual bool GetPrivateConfigSubgroups(const PluginID & ID, const wxString & group, wxArrayString & subgroups);
virtual bool GetPrivateConfig(const PluginID & ID, const wxString & group, const wxString & key, wxString & value, const wxString & defval = _T(""));
@ -280,6 +282,7 @@ private:
wxFileConfig *GetSettings();
bool HasGroup(const wxString & group);
bool GetSubgroups(const wxString & group, wxArrayString & subgroups);
bool GetConfig(const wxString & key, wxString & value, const wxString & defval = L"");

View File

@ -69,6 +69,11 @@ static const int kUserPresetsID = 31000;
static const int kDeletePresetID = 32000;
static const int kFactoryPresetsID = 33000;
const wxString Effect::kUserPresetIdent = wxT("User Preset:");
const wxString Effect::kFactoryPresetIdent = wxT("Factory Preset:");
const wxString Effect::kCurrentSettingsIdent = wxT("<Current Settings>");
const wxString Effect::kFactoryDefaultsIdent = wxT("<Factory Defaults>");
WX_DECLARE_VOIDPTR_HASH_MAP( bool, t2bHash );
Effect::Effect()
@ -110,15 +115,26 @@ Effect::Effect()
AudacityProject *p = GetActiveProject();
mProjectRate = p ? p->GetRate() : 44100;
mIsBatch = false;
}
Effect::~Effect()
{
delete mOutputTracks;
if (mOutputTracks)
{
delete mOutputTracks;
}
if (mWarper != NULL)
{
delete mWarper;
}
if (mUIDialog)
{
mUIDialog->Close();
}
}
// EffectIdentInterface implementation
@ -485,11 +501,24 @@ bool Effect::RealtimeProcessEnd()
bool Effect::ShowInterface(wxWindow *parent, bool forceModal)
{
if (!IsInteractive())
{
return true;
}
if (mUIDialog)
{
mUIDialog->Close(true);
return false;
}
if (mClient)
{
return mClient->ShowInterface(parent, forceModal);
}
mParent = parent;
mUIDialog = CreateUI(parent, this);
if (!mUIDialog)
{
@ -500,9 +529,17 @@ bool Effect::ShowInterface(wxWindow *parent, bool forceModal)
mUIDialog->Fit();
mUIDialog->SetMinSize(mUIDialog->GetSize());
bool res = mUIDialog->ShowModal() != 0;
if (SupportsRealtime() && !forceModal)
{
mUIDialog->Show();
// Return false to bypass effect processing
return false;
}
bool res = mUIDialog->ShowModal() != 0;
mUIDialog = NULL;
mParent = NULL;
return res;
}
@ -529,11 +566,6 @@ bool Effect::SetAutomationParameters(EffectAutomationParameters & parms)
bool Effect::LoadUserPreset(const wxString & name)
{
if (!SupportsAutomation())
{
return true;
}
if (mClient)
{
return mClient->LoadUserPreset(name);
@ -550,11 +582,6 @@ bool Effect::LoadUserPreset(const wxString & name)
bool Effect::SaveUserPreset(const wxString & name)
{
if (!SupportsAutomation())
{
return true;
}
if (mClient)
{
return mClient->SaveUserPreset(name);
@ -610,7 +637,7 @@ bool Effect::PopulateUI(wxWindow *parent)
mUIParent = parent;
mUIParent->PushEventHandler(this);
LoadUserPreset(GetCurrentSettingsGroup());
// LoadUserPreset(GetCurrentSettingsGroup());
ShuttleGui S(mUIParent, eIsCreating);
PopulateOrExchange(S);
@ -782,6 +809,10 @@ wxString Effect::GetFactoryDefaultsGroup()
}
// ConfigClientInterface implementation
bool Effect::HasSharedConfigGroup(const wxString & group)
{
return PluginManager::Get().HasSharedConfigGroup(GetID(), group);
}
bool Effect::GetSharedConfigSubgroups(const wxString & group, wxArrayString & subgroups)
{
@ -858,6 +889,11 @@ bool Effect::RemoveSharedConfig(const wxString & group, const wxString & key)
return PluginManager::Get().RemoveSharedConfig(GetID(), group, key);
}
bool Effect::HasPrivateConfigGroup(const wxString & group)
{
return PluginManager::Get().HasPrivateConfigGroup(GetID(), group);
}
bool Effect::GetPrivateConfigSubgroups(const wxString & group, wxArrayString & subgroups)
{
return PluginManager::Get().GetPrivateConfigSubgroups(GetID(), group, subgroups);
@ -997,17 +1033,45 @@ bool Effect::GetAutomationParameters(wxString & parms)
bool Effect::SetAutomationParameters(const wxString & parms)
{
EffectAutomationParameters eap(parms);
if (!SetAutomationParameters(eap))
wxString preset = parms;
bool success = false;
if (preset.StartsWith(kUserPresetIdent))
{
preset.Replace(kUserPresetIdent, wxEmptyString, false);
success = LoadUserPreset(GetUserPresetsGroup(preset));
}
else if (preset.StartsWith(kFactoryPresetIdent))
{
preset.Replace(kFactoryPresetIdent, wxEmptyString, false);
wxArrayString presets = GetFactoryPresets();
success = LoadFactoryPreset(presets.Index(preset));
}
else if (preset.StartsWith(kCurrentSettingsIdent))
{
preset.Replace(kCurrentSettingsIdent, wxEmptyString, false);
success = LoadUserPreset(GetCurrentSettingsGroup());
}
else if (preset.StartsWith(kFactoryDefaultsIdent))
{
preset.Replace(kFactoryDefaultsIdent, wxEmptyString, false);
success = LoadUserPreset(GetFactoryDefaultsGroup());
}
else
{
EffectAutomationParameters eap(parms);
success = SetAutomationParameters(eap);
}
if (!success)
{
wxMessageBox(
wxString::Format(
_("Could not set parameters of effect %s\n to %s."),
_("Could not update effect \"%s\" with:\n%s"),
GetName().c_str(),
parms.c_str()
preset.c_str()
)
);
return false;
}
@ -1019,6 +1083,52 @@ bool Effect::SetAutomationParameters(const wxString & parms)
return TransferDataToWindow();
}
wxArrayString Effect::GetUserPresets()
{
wxArrayString presets;
GetPrivateConfigSubgroups(GetUserPresetsGroup(wxEmptyString), presets);
presets.Sort();
return presets;
}
bool Effect::HasCurrentSettings()
{
return HasPrivateConfigGroup(GetCurrentSettingsGroup());
}
bool Effect::HasFactoryDefaults()
{
return HasPrivateConfigGroup(GetFactoryDefaultsGroup());
}
wxString Effect::GetPreset(wxWindow * parent)
{
EffectPresetsDialog dlg(parent, this);
dlg.Layout();
dlg.Fit();
dlg.SetSize(dlg.GetMinSize());
if (dlg.ShowModal())
{
return dlg.GetSelected();
}
return wxEmptyString;
}
bool Effect::IsBatchProcessing()
{
return mIsBatch;
}
void Effect::SetBatchProcessing(bool enable)
{
mIsBatch = enable;
}
bool Effect::DoEffect(wxWindow *parent,
double projectRate,
TrackList *list,
@ -1062,7 +1172,7 @@ bool Effect::DoEffect(wxWindow *parent,
// Prompting will be bypassed when applying an effect that has already
// been configured, e.g. repeating the last effect on a different selection.
if (shouldPrompt && !PromptUser(parent))
if (shouldPrompt && IsInteractive() && !PromptUser(parent))
{
return false;
}
@ -1101,28 +1211,12 @@ bool Effect::Init()
return true;
}
bool Effect::PromptUser(wxWindow *parent, bool isBatch)
// Remove this method once NoiseReduction gets migrated
bool Effect::PromptUser(wxWindow *parent)
{
if (IsInteractive())
{
mParent = parent;
bool res = ShowInterface(parent, isBatch);
// Really need to clean this up...should get easier when
// all effects get converted.
if (!res || (SupportsRealtime() && isBatch))
{
// Return false to force DoEffect() to skip processing since
// this UI has either been shown modeless or there was an error.
return false;
}
}
return true;
return ShowInterface(parent, IsBatchProcessing());
}
int Effect::GetPass()
{
return mPass;
@ -2676,6 +2770,7 @@ bool EffectUIHost::Initialize()
mSupportsRealtime = mEffect->SupportsRealtime();
mIsGUI = mClient->IsGraphicalUI();
mIsBatch = mEffect->IsBatchProcessing();
wxBitmapButton *bb;
@ -2704,93 +2799,106 @@ bool EffectUIHost::Initialize()
bs->Add(5, 5);
if (!mIsGUI)
if (!mIsBatch)
{
if (!mIsGUI)
{
if (mSupportsRealtime)
{
mPlayToggleBtn = new wxButton(bar, kPlayID, _("Start &Playback"));
mPlayToggleBtn->SetToolTip(_("Start and stop playback"));
bs->Add(mPlayToggleBtn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
}
else if (mEffect->GetType() != EffectTypeAnalyze)
{
mPlayToggleBtn = new wxButton(bar, kPlayID, _("&Preview"));
mPlayToggleBtn->SetToolTip(_("Preview effect"));
bs->Add(mPlayToggleBtn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
}
}
else
{
mPlayBM = CreateBitmap(effect_play_xpm, true, false);
mPlayDisabledBM = CreateBitmap(effect_play_disabled_xpm, true, false);
mStopBM = CreateBitmap(effect_stop_xpm, true, false);
mStopDisabledBM = CreateBitmap(effect_stop_disabled_xpm, true, false);
bb = new wxBitmapButton(bar, kPlayID, mPlayBM);
bb->SetBitmapDisabled(mPlayDisabledBM);
mPlayBtn = bb;
bs->Add(mPlayBtn);
if (!mSupportsRealtime)
{
mPlayBtn->SetToolTip(_("Preview effect"));
#if defined(__WXMAC__)
mPlayBtn->SetName(_("Preview effect"));
#else
mPlayBtn->SetLabel(_("&Preview effect"));
#endif
}
}
if (mSupportsRealtime)
{
mPlayToggleBtn = new wxButton(bar, kPlayID, _("Start &Playback"));
mPlayToggleBtn->SetToolTip(_("Start and stop playback"));
bs->Add(mPlayToggleBtn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
}
else if (mEffect->GetType() != EffectTypeAnalyze)
{
mPlayToggleBtn = new wxButton(bar, kPlayID, _("&Preview"));
mPlayToggleBtn->SetToolTip(_("Preview effect"));
bs->Add(mPlayToggleBtn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
}
}
else
{
mPlayBM = CreateBitmap(effect_play_xpm, true, false);
mPlayDisabledBM = CreateBitmap(effect_play_disabled_xpm, true, false);
mStopBM = CreateBitmap(effect_stop_xpm, true, false);
mStopDisabledBM = CreateBitmap(effect_stop_disabled_xpm, true, false);
bb = new wxBitmapButton(bar, kPlayID, mPlayBM);
bb->SetBitmapDisabled(mPlayDisabledBM);
mPlayBtn = bb;
bs->Add(mPlayBtn);
if (!mSupportsRealtime)
{
mPlayBtn->SetToolTip(_("Preview effect"));
if (!mIsGUI)
{
mRewindBtn = new wxButton(bar, kRewindID, _("Skip &Backward"));
bs->Add(mRewindBtn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
}
else
{
bb = new wxBitmapButton(bar, kRewindID, CreateBitmap(effect_rewind_xpm, true, true));
bb->SetBitmapDisabled(CreateBitmap(effect_rewind_disabled_xpm, true, true));
mRewindBtn = bb;
#if defined(__WXMAC__)
mPlayBtn->SetName(_("Preview effect"));
mRewindBtn->SetName(_("Skip &Backward"));
#else
mPlayBtn->SetLabel(_("&Preview effect"));
mRewindBtn->SetLabel(_("Skip &Backward"));
#endif
}
}
bs->Add(mRewindBtn);
}
mRewindBtn->SetToolTip(_("Skip backward"));
if (mSupportsRealtime)
{
if (!mIsGUI)
{
mRewindBtn = new wxButton(bar, kRewindID, _("Skip &Backward"));
bs->Add(mRewindBtn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
}
else
{
bb = new wxBitmapButton(bar, kRewindID, CreateBitmap(effect_rewind_xpm, true, true));
bb->SetBitmapDisabled(CreateBitmap(effect_rewind_disabled_xpm, true, true));
mRewindBtn = bb;
if (!mIsGUI)
{
mFFwdBtn = new wxButton(bar, kFFwdID, _("Skip &Forward"));
bs->Add(mFFwdBtn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
}
else
{
bb = new wxBitmapButton(bar, kFFwdID, CreateBitmap(effect_ffwd_xpm, true, true));
bb->SetBitmapDisabled(CreateBitmap(effect_ffwd_disabled_xpm, true, true));
mFFwdBtn = bb;
#if defined(__WXMAC__)
mRewindBtn->SetName(_("Skip &Backward"));
mFFwdBtn->SetName(_("Skip &Foreward"));
#else
mRewindBtn->SetLabel(_("Skip &Backward"));
mFFwdBtn->SetLabel(_("Skip &Foreward"));
#endif
bs->Add(mRewindBtn);
}
mRewindBtn->SetToolTip(_("Skip backward"));
bs->Add(mFFwdBtn);
}
mFFwdBtn->SetToolTip(_("Skip forward"));
if (!mIsGUI)
{
mFFwdBtn = new wxButton(bar, kFFwdID, _("Skip &Forward"));
bs->Add(mFFwdBtn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
}
else
{
bb = new wxBitmapButton(bar, kFFwdID, CreateBitmap(effect_ffwd_xpm, true, true));
bb->SetBitmapDisabled(CreateBitmap(effect_ffwd_disabled_xpm, true, true));
mFFwdBtn = bb;
#if defined(__WXMAC__)
mFFwdBtn->SetName(_("Skip &Foreward"));
#else
mFFwdBtn->SetLabel(_("Skip &Foreward"));
#endif
bs->Add(mFFwdBtn);
}
mFFwdBtn->SetToolTip(_("Skip forward"));
bs->Add(5, 5);
bs->Add(5, 5);
mEnableCb = new wxCheckBox(bar, kEnableID, _("&Enable"));
mEnableCb->SetValue(mEnabled);
mEnableCb->SetName(_("Enable"));
bs->Add(mEnableCb, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
mEnableCb = new wxCheckBox(bar, kEnableID, _("&Enable"));
mEnableCb->SetValue(mEnabled);
mEnableCb->SetName(_("Enable"));
bs->Add(mEnableCb, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, margin);
}
}
bar->SetSizerAndFit(bs);
wxSizer *s = CreateStdButtonSizer(this, eApplyButton | /*eCloseButton | */(mEffect->mUIDebug ? eDebugButton : 0), bar);
long buttons = eApplyButton;
if (!mIsBatch)
{
// buttons += eCloseButton;
if (mEffect->mUIDebug)
{
buttons += eDebugButton;
}
}
wxSizer *s = CreateStdButtonSizer(this, buttons, bar);
vs->Add(s, 0, wxEXPAND | wxALIGN_CENTER_VERTICAL);
SetSizer(vs);
@ -2853,7 +2961,7 @@ void EffectUIHost::OnApply(wxCommandEvent & evt)
return;
}
if (mEffect->GetType() != EffectTypeGenerate && mProject->mViewInfo.selectedRegion.isPoint())
if (!mIsBatch && mEffect->GetType() != EffectTypeGenerate && mProject->mViewInfo.selectedRegion.isPoint())
{
wxMessageBox(_("You must select audio in the project window."));
return;
@ -3305,6 +3413,11 @@ wxBitmap EffectUIHost::CreateBitmap(const char *xpm[], bool up, bool pusher)
void EffectUIHost::UpdateControls()
{
if (mIsBatch)
{
return;
}
if (mCapturing || mDisableTransport)
{
// Don't allow focus to get trapped
@ -3425,4 +3538,161 @@ void EffectUIHost::CleanupRealtime()
mInitialized = false;
}
}
}
///////////////////////////////////////////////////////////////////////////////
//
// EffectPresetsDialog
//
///////////////////////////////////////////////////////////////////////////////
enum
{
ID_Type = 10000
};
BEGIN_EVENT_TABLE(EffectPresetsDialog, wxDialog)
EVT_CHOICE(ID_Type, EffectPresetsDialog::OnType)
EVT_LISTBOX_DCLICK(wxID_ANY, EffectPresetsDialog::OnOk)
EVT_BUTTON(wxID_OK, EffectPresetsDialog::OnOk)
EVT_BUTTON(wxID_CANCEL, EffectPresetsDialog::OnCancel)
END_EVENT_TABLE()
EffectPresetsDialog::EffectPresetsDialog(wxWindow *parent, Effect *effect)
: wxDialog(parent, wxID_ANY, wxString(_("Select Preset")))
{
ShuttleGui S(this, eIsCreating);
S.StartVerticalLay();
{
S.StartTwoColumn();
S.SetStretchyCol(1);
{
wxArrayString empty;
S.AddPrompt(_("Type:"));
mType = S.Id(ID_Type).AddChoice(wxT(""), wxT(""), &empty);
mType->SetSelection(0);
S.AddPrompt(_("&Preset:"));
mPresets = S.AddListBox(&empty, wxLB_SINGLE | wxLB_NEEDED_SB );
}
S.EndTwoColumn();
S.AddStandardButtons();
}
S.EndVerticalLay();
mUserPresets = effect->GetUserPresets();
mFactoryPresets = effect->GetFactoryPresets();
if (mUserPresets.GetCount() > 0)
{
mType->Append(_("User Presets"));
}
if (mFactoryPresets.GetCount() > 0)
{
mType->Append(_("Factory Presets"));
}
if (effect->HasCurrentSettings())
{
mType->Append(_("Current Settings"));
}
if (effect->HasFactoryDefaults())
{
mType->Append(_("Factory Defaults"));
}
UpdateUI();
}
EffectPresetsDialog::~EffectPresetsDialog()
{
}
void EffectPresetsDialog::UpdateUI()
{
int selected = mType->GetSelection();
if (selected == wxNOT_FOUND)
{
selected = 0;
mType->SetSelection(selected);
}
wxString type = mType->GetString(selected);
if (type.IsSameAs(_("User Presets")))
{
selected = mPresets->GetSelection();
if (selected == wxNOT_FOUND)
{
selected = 0;
}
mPresets->Clear();
mPresets->Append(mUserPresets);
mPresets->Enable(true);
mPresets->SetSelection(selected);
mSelection = Effect::kUserPresetIdent + mPresets->GetString(selected);
}
else if (type.IsSameAs(_("Factory Presets")))
{
selected = mPresets->GetSelection();
if (selected == wxNOT_FOUND)
{
selected = 0;
}
mPresets->Clear();
for (size_t i = 0, cnt = mFactoryPresets.GetCount(); i < cnt; i++)
{
wxString label = mFactoryPresets[i];
if (label.IsEmpty())
{
label = _("None");
}
mPresets->Append(label);
}
mPresets->Enable(true);
mPresets->SetSelection(selected);
mSelection = Effect::kFactoryPresetIdent + mPresets->GetString(selected);
}
else if (type.IsSameAs(_("Current Settings")))
{
mPresets->Clear();
mPresets->Enable(false);
mSelection = Effect::kCurrentSettingsIdent;
}
else if (type.IsSameAs(_("Factory Defaults")))
{
mPresets->Clear();
mPresets->Enable(false);
mSelection = Effect::kFactoryDefaultsIdent;
}
}
void EffectPresetsDialog::OnType(wxCommandEvent & WXUNUSED(evt))
{
UpdateUI();
}
void EffectPresetsDialog::OnOk(wxCommandEvent & WXUNUSED(evt))
{
UpdateUI();
EndModal(true);
}
void EffectPresetsDialog::OnCancel(wxCommandEvent & WXUNUSED(evt))
{
mSelection = wxEmptyString;
EndModal(false);
}
wxString EffectPresetsDialog::GetSelected() const
{
return mSelection;
}

View File

@ -158,6 +158,7 @@ class AUDACITY_DLL_API Effect : public wxEvtHandler,
// ConfigClientInterface implementation
virtual bool HasSharedConfigGroup(const wxString & group);
virtual bool GetSharedConfigSubgroups(const wxString & group, wxArrayString & subgroups);
virtual bool GetSharedConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval = wxEmptyString);
@ -177,6 +178,7 @@ class AUDACITY_DLL_API Effect : public wxEvtHandler,
virtual bool RemoveSharedConfigSubgroup(const wxString & group);
virtual bool RemoveSharedConfig(const wxString & group, const wxString & key);
virtual bool HasPrivateConfigGroup(const wxString & group);
virtual bool GetPrivateConfigSubgroups(const wxString & group, wxArrayString & subgroups);
virtual bool GetPrivateConfig(const wxString & group, const wxString & key, wxString & value, const wxString & defval = wxEmptyString);
@ -206,6 +208,14 @@ class AUDACITY_DLL_API Effect : public wxEvtHandler,
virtual bool GetAutomationParameters(wxString & parms);
virtual bool SetAutomationParameters(const wxString & parms);
virtual wxArrayString GetUserPresets();
virtual bool HasCurrentSettings();
virtual bool HasFactoryDefaults();
virtual wxString GetPreset(wxWindow * parent);
virtual bool IsBatchProcessing();
virtual void SetBatchProcessing(bool enable);
void SetPresetParameters( const wxArrayString * Names, const wxArrayString * Values ){
if( Names ) mPresetNames = *Names;
if( Values ) mPresetValues = *Values;
@ -228,7 +238,7 @@ class AUDACITY_DLL_API Effect : public wxEvtHandler,
bool IsRealtimeActive();
virtual bool IsHidden();
//
// protected virtual methods
//
@ -245,7 +255,7 @@ protected:
// This method will not always be called (for example if a user
// repeats an effect) but if it is called, it will be called
// after Init.
virtual bool PromptUser(wxWindow *parent = NULL, bool isBatch = false);
virtual bool PromptUser(wxWindow *parent);
// Check whether effect should be skipped
// Typically this is only useful in automation, for example
@ -374,6 +384,8 @@ protected:
private:
wxWindow *mParent;
bool mIsBatch;
double mDuration;
bool mUIDebug;
@ -404,9 +416,15 @@ private:
wxCriticalSection mRealtimeSuspendLock;
int mRealtimeSuspendCount;
const static wxString kUserPresetIdent;
const static wxString kFactoryPresetIdent;
const static wxString kCurrentSettingsIdent;
const static wxString kFactoryDefaultsIdent;
friend class EffectManager;// so it can call PromptUser in support of batch commands.
friend class EffectRack;
friend class EffectUIHost;
friend class EffectPresetsDialog;
};
@ -507,6 +525,7 @@ private:
bool mInitialized;
bool mSupportsRealtime;
bool mIsGUI;
bool mIsBatch;
#if defined(__WXMAC__)
bool mIsModal;
@ -540,6 +559,32 @@ private:
DECLARE_EVENT_TABLE();
};
class EffectPresetsDialog : public wxDialog
{
public:
EffectPresetsDialog(wxWindow *parent, Effect *effect);
virtual ~EffectPresetsDialog();
wxString GetSelected() const;
private:
void UpdateUI();
void OnType(wxCommandEvent & evt);
void OnOk(wxCommandEvent & evt);
void OnCancel(wxCommandEvent & evt);
private:
wxChoice *mType;
wxListBox *mPresets;
wxArrayString mFactoryPresets;
wxArrayString mUserPresets;
wxString mSelection;
DECLARE_EVENT_TABLE();
};
// Utility functions
inline float TrapFloat(float x, float min, float max)

View File

@ -77,7 +77,8 @@ bool EffectManager::DoEffect(const PluginID & ID,
TrackList *list,
TrackFactory *factory,
SelectedRegion *selectedRegion,
bool shouldPrompt /* = true */)
bool shouldPrompt /* = true */,
bool isBatch /* = false */)
{
Effect *effect = GetEffect(ID);
@ -94,12 +95,18 @@ bool EffectManager::DoEffect(const PluginID & ID,
}
#endif
return effect->DoEffect(parent,
projectRate,
list,
factory,
selectedRegion,
shouldPrompt);
effect->SetBatchProcessing(isBatch);
bool res = effect->DoEffect(parent,
projectRate,
list,
factory,
selectedRegion,
shouldPrompt);
effect->SetBatchProcessing(false);
return res;
}
wxString EffectManager::GetEffectName(const PluginID & ID)
@ -176,12 +183,19 @@ bool EffectManager::SetEffectParameters(const PluginID & ID, const wxString & pa
{
Effect *effect = GetEffect(ID);
if (effect)
if (!effect)
{
return effect->SetAutomationParameters(params);
return false;
}
return false;
EffectAutomationParameters eap(params);
if (eap.HasEntry(wxT("Use Preset")))
{
return effect->SetAutomationParameters(eap.Read(wxT("Use Preset")));
}
return effect->SetAutomationParameters(params);
}
bool EffectManager::PromptUser(const PluginID & ID, wxWindow *parent)
@ -191,12 +205,54 @@ bool EffectManager::PromptUser(const PluginID & ID, wxWindow *parent)
if (effect)
{
result = effect->PromptUser(parent, true);
effect->SetBatchProcessing(true);
result = effect->PromptUser(parent);
effect->SetBatchProcessing(false);
}
return result;
}
bool EffectManager::HasPresets(const PluginID & ID)
{
Effect *effect = GetEffect(ID);
if (!effect)
{
return false;
}
return effect->GetUserPresets().GetCount() > 0 ||
effect->GetFactoryPresets().GetCount() > 0 ||
effect->HasCurrentSettings() ||
effect->HasFactoryDefaults();
}
wxString EffectManager::GetPreset(const PluginID & ID, wxWindow * parent)
{
Effect *effect = GetEffect(ID);
if (!effect)
{
return wxEmptyString;
}
wxString preset = effect->GetPreset(parent);
if (preset.IsEmpty())
{
return preset;
}
EffectAutomationParameters eap;
eap.Write(wxT("Use Preset"), preset);
eap.GetParameters(preset);
return preset;
}
#if defined(EXPERIMENTAL_EFFECTS_RACK)
EffectRack *EffectManager::GetRack()
{
@ -633,3 +689,4 @@ const PluginID & EffectManager::GetEffectByIdentifier(const wxString & strTarget
return empty;;
}

View File

@ -21,6 +21,12 @@ effects.
#ifndef __AUDACITY_EFFECTMANAGER__
#define __AUDACITY_EFFECTMANAGER__
#include <wx/choice.h>
#include <wx/dialog.h>
#include <wx/event.h>
#include <wx/listbox.h>
#include <wx/string.h>
#include "audacity/EffectInterface.h"
#include "../PluginManager.h"
#include "Effect.h"
@ -65,7 +71,8 @@ public:
TrackList *list,
TrackFactory *factory,
SelectedRegion *selectedRegion,
bool shouldPrompt = true);
bool shouldPrompt = true,
bool isBatch = false);
wxString GetEffectName(const PluginID & ID);
wxString GetEffectIdentifier(const PluginID & ID);
@ -76,6 +83,8 @@ public:
wxString GetEffectParameters(const PluginID & ID);
bool SetEffectParameters(const PluginID & ID, const wxString & params);
bool PromptUser(const PluginID & ID, wxWindow *parent);
bool HasPresets(const PluginID & ID);
wxString GetPreset(const PluginID & ID, wxWindow * parent);
// Realtime effect processing
bool RealtimeIsActive();
@ -126,6 +135,7 @@ private:
friend class EffectRack;
#endif
};

View File

@ -446,7 +446,7 @@ bool EffectNoiseReduction::CheckWhetherSkipEffect()
return false;
}
bool EffectNoiseReduction::PromptUser(wxWindow *parent, bool isBatch)
bool EffectNoiseReduction::PromptUser(wxWindow *parent)
{
// We may want to twiddle the levels if we are setting
// from an automation dialog, the only case in which we can

View File

@ -40,7 +40,7 @@ public:
// using Effect::TrackProgress;
virtual bool PromptUser(wxWindow *parent = NULL, bool isBatch = false);
virtual bool PromptUser(wxWindow *parent);
virtual bool Init();
virtual bool CheckWhetherSkipEffect();