mirror of
https://github.com/cookiengineer/audacity
synced 2025-12-24 17:41:13 +01:00
Migrating the remaining effects
This brings the builtin, LV2, and VAMP effects inline with the Audio Units, LADSPA, and VST effects. All effects now share a common UI. This gives all effects (though not implemented for all): User and factory preset capability Preset import/export capability Shared or private configuration options Builtin effects can now be migrated to RTP, depending on algorithm. LV2 effects now support graphical interfaces if the plugin supplies one. Nyquist prompt enhanced to provide some features of the Nyquist Workbench. It may not look like it, but this was a LOT of work, so trust me, there WILL be problems and everything effect related should be suspect. Keep a sharp eye (or two) open.
This commit is contained in:
455
src/Menus.cpp
455
src/Menus.cpp
@@ -178,28 +178,10 @@ AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *pr
|
||||
mPluginID = pluginID;
|
||||
}
|
||||
|
||||
#if defined(EFFECT_CATEGORIES)
|
||||
AudacityProjectCommandFunctor::AudacityProjectCommandFunctor(AudacityProject *project,
|
||||
audCommandListFunction commandFunction,
|
||||
wxArrayInt explicitIndices)
|
||||
{
|
||||
mProject = project;
|
||||
mCommandFunction = NULL;
|
||||
mCommandKeyFunction = NULL;
|
||||
mCommandListFunction = commandFunction;
|
||||
mCommandPluginFunction = NULL;
|
||||
mExplicitIndices = explicitIndices;
|
||||
}
|
||||
#endif
|
||||
|
||||
void AudacityProjectCommandFunctor::operator()(int index, const wxEvent * evt)
|
||||
{
|
||||
if (mCommandPluginFunction)
|
||||
(mProject->*(mCommandPluginFunction)) (mPluginID);
|
||||
#if defined(EFFECT_CATEGORIES)
|
||||
else if (mCommandListFunction && mExplicitIndices.GetCount() > 0)
|
||||
(mProject->*(mCommandListFunction)) (mExplicitIndices[index]);
|
||||
#endif
|
||||
(mProject->*(mCommandPluginFunction)) (mPluginID, AudacityProject::OnEffectFlags::kNone);
|
||||
else if (mCommandListFunction)
|
||||
(mProject->*(mCommandListFunction)) (index);
|
||||
else if (mCommandKeyFunction)
|
||||
@@ -992,44 +974,10 @@ void AudacityProject::CreateMenusAndCommands()
|
||||
c->BeginMenu(_("&Generate"));
|
||||
c->SetDefaultFlags(AudioIONotBusyFlag, AudioIONotBusyFlag);
|
||||
|
||||
#ifndef EFFECT_CATEGORIES
|
||||
PopulateEffectsMenu(c,
|
||||
EffectTypeGenerate,
|
||||
AudioIONotBusyFlag,
|
||||
AudioIONotBusyFlag);
|
||||
#else
|
||||
|
||||
int flags;
|
||||
|
||||
flags = INSERT_EFFECT | BUILTIN_EFFECT | PLUGIN_EFFECT;
|
||||
EffectCategory* ac =
|
||||
em.LookupCategory(wxT("http://lv2plug.in/ns/lv2core#GeneratorPlugin"));
|
||||
CategorySet roots = ac->GetSubCategories();
|
||||
EffectSet generators = ac->GetEffects();
|
||||
EffectSet topLevel = CreateEffectSubmenus(c, roots, flags, 0);
|
||||
std::copy(generators.begin(), generators.end(),
|
||||
std::insert_iterator<EffectSet>(topLevel, topLevel.begin()));
|
||||
AddEffectsToMenu(c, topLevel);
|
||||
|
||||
// Add all uncategorised effects in a special submenu
|
||||
EffectSet unsorted =
|
||||
em.GetUnsortedEffects(flags);
|
||||
if (unsorted.size() > 0) {
|
||||
c->AddSeparator();
|
||||
c->BeginSubMenu(_("Unsorted"));
|
||||
names.Clear();
|
||||
indices.Clear();
|
||||
EffectSet::const_iterator iter;
|
||||
for (iter = unsorted.begin(); iter != unsorted.end(); ++iter) {
|
||||
names.Add((*iter)->GetEffectName());
|
||||
indices.Add((*iter)->GetEffectID());
|
||||
}
|
||||
c->AddItemList(wxT("Generate"), names,
|
||||
FNI(OnProcessAny, indices), true);
|
||||
c->EndSubMenu();
|
||||
}
|
||||
|
||||
#endif // EFFECT_CATEGORIES
|
||||
|
||||
c->EndMenu();
|
||||
|
||||
@@ -1040,7 +988,7 @@ void AudacityProject::CreateMenusAndCommands()
|
||||
c->BeginMenu(_("Effe&ct"));
|
||||
|
||||
wxString buildMenuLabel;
|
||||
if (mLastEffectType != 0) {
|
||||
if (!mLastEffect.IsEmpty()) {
|
||||
buildMenuLabel.Printf(_("Repeat %s"),
|
||||
EffectManager::Get().GetEffectName(mLastEffect).c_str());
|
||||
}
|
||||
@@ -1053,40 +1001,10 @@ void AudacityProject::CreateMenusAndCommands()
|
||||
|
||||
c->AddSeparator();
|
||||
|
||||
// this is really ugly but we need to keep all the old code to get any
|
||||
// effects at all in the menu when EFFECT_CATEGORIES is undefined
|
||||
|
||||
#ifndef EFFECT_CATEGORIES
|
||||
PopulateEffectsMenu(c,
|
||||
EffectTypeProcess,
|
||||
AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag,
|
||||
TracksExistFlag | IsRealtimeNotActiveFlag);
|
||||
#else
|
||||
int flags = PROCESS_EFFECT | BUILTIN_EFFECT | PLUGIN_EFFECT | ADVANCED_EFFECT;
|
||||
// The categories form a DAG, so we start at the roots (the categories
|
||||
// without incoming links)
|
||||
CategorySet roots = em.GetRootCategories();
|
||||
EffectSet topLevel = CreateEffectSubmenus(c, roots, flags, 0);
|
||||
AddEffectsToMenu(c, topLevel);
|
||||
|
||||
// Add all uncategorised effects in a special submenu
|
||||
EffectSet unsorted =
|
||||
em.GetUnsortedEffects(flags);
|
||||
if (unsorted.size() > 0) {
|
||||
c->AddSeparator();
|
||||
c->BeginSubMenu(_("Unsorted"));
|
||||
names.Clear();
|
||||
indices.Clear();
|
||||
EffectSet::const_iterator iter;
|
||||
for (iter = unsorted.begin(); iter != unsorted.end(); ++iter) {
|
||||
names.Add((*iter)->GetEffectName());
|
||||
indices.Add((*iter)->GetEffectID());
|
||||
}
|
||||
c->AddItemList(wxT("Effect"), names, FNI(OnProcessAny, indices), true);
|
||||
c->EndSubMenu();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
c->EndMenu();
|
||||
|
||||
@@ -1103,42 +1021,10 @@ void AudacityProject::CreateMenusAndCommands()
|
||||
AudioIONotBusyFlag | WaveTracksSelectedFlag | TimeSelectedFlag,
|
||||
AudioIONotBusyFlag | WaveTracksSelectedFlag | TimeSelectedFlag);
|
||||
|
||||
#ifndef EFFECT_CATEGORIES
|
||||
PopulateEffectsMenu(c,
|
||||
EffectTypeAnalyze,
|
||||
AudioIONotBusyFlag | TimeSelectedFlag | WaveTracksSelectedFlag,
|
||||
TracksExistFlag | IsRealtimeNotActiveFlag);
|
||||
#else
|
||||
|
||||
flags = ANALYZE_EFFECT | BUILTIN_EFFECT | PLUGIN_EFFECT;
|
||||
EffectCategory* ac =
|
||||
em.LookupCategory(wxT("http://lv2plug.in/ns/lv2core#AnalyserPlugin"));
|
||||
CategorySet roots = ac->GetSubCategories();
|
||||
EffectSet analyzers = ac->GetEffects();
|
||||
EffectSet topLevel = CreateEffectSubmenus(c, roots, flags, 0);
|
||||
std::copy(analyzers.begin(), analyzers.end(),
|
||||
std::insert_iterator<EffectSet>(topLevel, topLevel.begin()));
|
||||
AddEffectsToMenu(c, topLevel);
|
||||
|
||||
// Add all uncategorised effects in a special submenu
|
||||
EffectSet unsorted =
|
||||
em.GetUnsortedEffects(flags);
|
||||
if (unsorted.size() > 0) {
|
||||
c->AddSeparator();
|
||||
c->BeginSubMenu(_("Unsorted"));
|
||||
names.Clear();
|
||||
indices.Clear();
|
||||
EffectSet::const_iterator iter;
|
||||
for (iter = unsorted.begin(); iter != unsorted.end(); ++iter) {
|
||||
names.Add((*iter)->GetEffectName());
|
||||
indices.Add((*iter)->GetEffectID());
|
||||
}
|
||||
c->AddItemList(wxT("Analyze"), names,
|
||||
FNI(OnProcessAny, indices), true);
|
||||
c->EndSubMenu();
|
||||
}
|
||||
|
||||
#endif // EFFECT_CATEGORIES
|
||||
|
||||
c->EndMenu();
|
||||
|
||||
@@ -1381,7 +1267,7 @@ void AudacityProject::PopulateEffectsMenu(CommandManager* c,
|
||||
|
||||
AddEffectMenuItems(c, defplugs, batchflags, realflags, true);
|
||||
|
||||
if (optplugs.GetCount())
|
||||
if (defplugs.GetCount() && optplugs.GetCount())
|
||||
{
|
||||
c->AddSeparator();
|
||||
}
|
||||
@@ -1421,13 +1307,6 @@ void AudacityProject::AddEffectMenuItems(CommandManager *c,
|
||||
|
||||
wxString name = plug->GetName();
|
||||
|
||||
// This goes away once everything has been converted to new format
|
||||
wxString stripped;
|
||||
if (name.EndsWith(wxT("..."), &stripped))
|
||||
{
|
||||
name = stripped;
|
||||
}
|
||||
|
||||
if (plug->IsEffectInteractive())
|
||||
{
|
||||
name += wxT("...");
|
||||
@@ -1492,13 +1371,6 @@ void AudacityProject::AddEffectMenuItems(CommandManager *c,
|
||||
|
||||
wxString name = plug->GetName();
|
||||
|
||||
// This goes away once everything has been converted to new format
|
||||
wxString stripped;
|
||||
if (name.EndsWith(wxT("..."), &stripped))
|
||||
{
|
||||
name = stripped;
|
||||
}
|
||||
|
||||
if (plug->IsEffectInteractive())
|
||||
{
|
||||
name += wxT("...");
|
||||
@@ -1635,73 +1507,6 @@ void AudacityProject::AddEffectMenuItemGroup(CommandManager *c,
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef EFFECT_CATEGORIES
|
||||
|
||||
EffectSet AudacityProject::CreateEffectSubmenus(CommandManager* c,
|
||||
const CategorySet& categories,
|
||||
int flags,
|
||||
unsigned submenuThreshold) {
|
||||
EffectSet topLevel;
|
||||
|
||||
CategorySet::const_iterator iter;
|
||||
for (iter = categories.begin(); iter != categories.end(); ++iter) {
|
||||
|
||||
EffectSet effects = (*iter)->GetAllEffects(flags);
|
||||
|
||||
// If the subgraph for this category only contains a single effect,
|
||||
// add it directly in this menu
|
||||
if (effects.size() <= submenuThreshold)
|
||||
topLevel.insert(effects.begin(), effects.end());
|
||||
|
||||
// If there are more than one effect, add a submenu for the category
|
||||
else if (effects.size() > 0) {
|
||||
|
||||
EffectSet directEffects = (*iter)->GetEffects(flags);
|
||||
CategorySet subCategories = (*iter)->GetSubCategories();
|
||||
CategorySet nonEmptySubCategories;
|
||||
|
||||
CategorySet::const_iterator sci;
|
||||
for (sci = subCategories.begin(); sci != subCategories.end(); ++sci) {
|
||||
if ((*sci)->GetAllEffects(flags).size() > 0)
|
||||
nonEmptySubCategories.insert(*sci);
|
||||
}
|
||||
|
||||
// If there are no direct effects and only one subcategory,
|
||||
// add the contents of that subcategory directly in this menu.
|
||||
if (directEffects.size() == 0 && nonEmptySubCategories.size() == 1) {
|
||||
EffectSet a = CreateEffectSubmenus(c, nonEmptySubCategories,
|
||||
flags);
|
||||
topLevel.insert(a.begin(), a.end());
|
||||
}
|
||||
|
||||
// Else, add submenus for the subcategories
|
||||
else {
|
||||
c->BeginSubMenu((*iter)->GetName());
|
||||
EffectSet a = CreateEffectSubmenus(c, subCategories, flags);
|
||||
a.insert(directEffects.begin(), directEffects.end());
|
||||
AddEffectsToMenu(c, a);
|
||||
c->EndSubMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return topLevel;
|
||||
}
|
||||
|
||||
void AudacityProject::AddEffectsToMenu(CommandManager* c,
|
||||
const EffectSet& effects) {
|
||||
wxArrayString names;
|
||||
wxArrayInt indices;
|
||||
EffectSet::const_iterator iter;
|
||||
for (iter = effects.begin(); iter != effects.end(); ++iter) {
|
||||
names.Add((*iter)->GetEffectName());
|
||||
indices.Add((*iter)->GetEffectID());
|
||||
}
|
||||
c->AddItemList(wxT("Effects"), names, FNI(OnProcessAny, indices), true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void AudacityProject::CreateRecentFilesMenu(CommandManager *c)
|
||||
{
|
||||
// Recent Files and Recent Projects menus
|
||||
@@ -1907,7 +1712,7 @@ wxUint32 AudacityProject::GetUpdateFlags()
|
||||
if (mUndoManager.UnsavedChanges())
|
||||
flags |= UnsavedChangesFlag;
|
||||
|
||||
if (!mLastEffect.empty())
|
||||
if (!mLastEffect.IsEmpty())
|
||||
flags |= HasLastEffectFlag;
|
||||
|
||||
if (mUndoManager.UndoAvailable())
|
||||
@@ -1948,10 +1753,8 @@ wxUint32 AudacityProject::GetUpdateFlags()
|
||||
else
|
||||
flags |= IsNotSyncLockedFlag;
|
||||
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
if (!EffectManager::Get().RealtimeIsActive())
|
||||
flags |= IsRealtimeNotActiveFlag;
|
||||
#endif
|
||||
|
||||
return flags;
|
||||
}
|
||||
@@ -3258,23 +3061,23 @@ void AudacityProject::OnZeroCrossing()
|
||||
|
||||
/// OnEffect() takes a PluginID and has the EffectManager execute the assocated effect.
|
||||
///
|
||||
/// At the moment flags are used only to indicate
|
||||
/// whether to prompt for parameters or whether to
|
||||
/// use the most recently stored values.
|
||||
///
|
||||
/// At some point we should change to specifying a
|
||||
/// parameter source - one of:
|
||||
/// + Prompt
|
||||
/// + Use previous values
|
||||
/// + Parse from a string that is passed in
|
||||
///
|
||||
/// DanH: I've added the third option as a temporary measure. I think this
|
||||
/// should eventually be done by having effects as Command objects.
|
||||
bool AudacityProject::OnEffect(int type,
|
||||
const PluginID & ID,
|
||||
wxString params,
|
||||
bool saveState)
|
||||
/// At the moment flags are used only to indicate whether to prompt for parameters and
|
||||
/// whether to save the state to history.
|
||||
bool AudacityProject::OnEffect(const PluginID & ID, int flags)
|
||||
{
|
||||
const PluginDescriptor *plug = PluginManager::Get().GetPlugin(ID);
|
||||
wxASSERT(plug != NULL);
|
||||
EffectType type = plug->GetEffectType();
|
||||
|
||||
// Make sure there's no activity since the effect is about to be applied
|
||||
// to the project's tracks. Mainly for Apply during RTP, but also used
|
||||
// for batch commands
|
||||
if (flags & OnEffectFlags::kConfigured)
|
||||
{
|
||||
OnStop();
|
||||
SelectAllIfNone();
|
||||
}
|
||||
|
||||
wxGetApp().SetMissingAliasedFileWarningShouldShow(true);
|
||||
|
||||
TrackListIterator iter(mTracks);
|
||||
@@ -3295,7 +3098,7 @@ bool AudacityProject::OnEffect(int type,
|
||||
|
||||
if (count == 0) {
|
||||
// No tracks were selected...
|
||||
if (type & INSERT_EFFECT) {
|
||||
if (type == EffectTypeGenerate) {
|
||||
// Create a new track for the generated audio...
|
||||
newTrack = mTrackFactory->NewWaveTrack();
|
||||
mTracks->Add(newTrack);
|
||||
@@ -3309,154 +3112,77 @@ bool AudacityProject::OnEffect(int type,
|
||||
|
||||
EffectManager & em = EffectManager::Get();
|
||||
|
||||
if (em.DoEffect(ID, this, type, mRate, mTracks, mTrackFactory,
|
||||
&mViewInfo.selectedRegion, params))
|
||||
{
|
||||
if (saveState)
|
||||
{
|
||||
wxString longDesc = em.GetEffectDescription(ID);
|
||||
wxString shortDesc = em.GetEffectName(ID);
|
||||
bool success = em.DoEffect(ID, this, mRate,
|
||||
mTracks, mTrackFactory,
|
||||
&mViewInfo.selectedRegion,
|
||||
!(flags & OnEffectFlags::kConfigured));
|
||||
|
||||
if (shortDesc.Length() > 3 && shortDesc.Right(3)==wxT("..."))
|
||||
shortDesc = shortDesc.Left(shortDesc.Length()-3);
|
||||
|
||||
PushState(longDesc, shortDesc);
|
||||
|
||||
// Only remember a successful effect, don't rmemeber insert,
|
||||
// or analyze effects.
|
||||
if ((type & (INSERT_EFFECT | ANALYZE_EFFECT))==0) {
|
||||
mLastEffect = ID;
|
||||
mLastEffectType = type;
|
||||
wxString lastEffectDesc;
|
||||
/* i18n-hint: %s will be the name of the effect which will be
|
||||
* repeated if this menu item is chosen */
|
||||
lastEffectDesc.Printf(_("Repeat %s"), shortDesc.c_str());
|
||||
mCommandManager.Modify(wxT("RepeatLastEffect"), lastEffectDesc);
|
||||
}
|
||||
}
|
||||
//STM:
|
||||
//The following automatically re-zooms after sound was generated.
|
||||
// IMO, it was disorienting, removing to try out without re-fitting
|
||||
//mchinen:12/14/08 reapplying for generate effects
|
||||
if ( type & INSERT_EFFECT)
|
||||
{
|
||||
if (count == 0 || (clean && mViewInfo.selectedRegion.t0() == 0.0))
|
||||
OnZoomFit();
|
||||
// mTrackPanel->Refresh(false);
|
||||
}
|
||||
RedrawProject();
|
||||
if (focus != NULL) {
|
||||
focus->SetFocus();
|
||||
}
|
||||
mTrackPanel->EnsureVisible(mTrackPanel->GetFirstSelectedTrack());
|
||||
|
||||
mTrackPanel->Refresh(false);
|
||||
} else {
|
||||
if (!success) {
|
||||
if (newTrack) {
|
||||
mTracks->Remove(newTrack);
|
||||
delete newTrack;
|
||||
mTrackPanel->Refresh(false);
|
||||
}
|
||||
|
||||
#if defined(EXPERIMENTAL_REALTIME_EFFECTS)
|
||||
// For now, we're limiting realtime preview to a single effect, so
|
||||
// make sure the menus reflect that fact that one may have just been
|
||||
// opened.
|
||||
UpdateMenus(false);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(flags & OnEffectFlags::kSkipState))
|
||||
{
|
||||
wxString shortDesc = em.GetEffectName(ID);
|
||||
wxString longDesc = em.GetEffectDescription(ID);
|
||||
PushState(longDesc, shortDesc);
|
||||
|
||||
// Only remember a successful effect, don't rmemeber insert,
|
||||
// or analyze effects.
|
||||
if (type == EffectTypeProcess) {
|
||||
mLastEffect = ID;
|
||||
wxString lastEffectDesc;
|
||||
/* i18n-hint: %s will be the name of the effect which will be
|
||||
* repeated if this menu item is chosen */
|
||||
lastEffectDesc.Printf(_("Repeat %s"), shortDesc.c_str());
|
||||
mCommandManager.Modify(wxT("RepeatLastEffect"), lastEffectDesc);
|
||||
}
|
||||
}
|
||||
|
||||
//STM:
|
||||
//The following automatically re-zooms after sound was generated.
|
||||
// IMO, it was disorienting, removing to try out without re-fitting
|
||||
//mchinen:12/14/08 reapplying for generate effects
|
||||
if (type == EffectTypeGenerate)
|
||||
{
|
||||
if (count == 0 || (clean && mViewInfo.selectedRegion.t0() == 0.0))
|
||||
OnZoomFit();
|
||||
// mTrackPanel->Refresh(false);
|
||||
}
|
||||
RedrawProject();
|
||||
if (focus != NULL) {
|
||||
focus->SetFocus();
|
||||
}
|
||||
mTrackPanel->EnsureVisible(mTrackPanel->GetFirstSelectedTrack());
|
||||
|
||||
mTrackPanel->Refresh(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AudacityProject::OnEffect(const PluginID & pluginID)
|
||||
{
|
||||
PluginManager & pm = PluginManager::Get();
|
||||
const PluginDescriptor *plug = pm.GetPlugin(pluginID);
|
||||
|
||||
int type;
|
||||
switch (plug->GetEffectType())
|
||||
{
|
||||
case EffectTypeGenerate:
|
||||
type = INSERT_EFFECT;
|
||||
break;
|
||||
|
||||
case EffectTypeProcess:
|
||||
type = PROCESS_EFFECT;
|
||||
break;
|
||||
|
||||
case EffectTypeAnalyze:
|
||||
type = ANALYZE_EFFECT;
|
||||
break;
|
||||
|
||||
case EffectTypeNone:
|
||||
type = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
type |= plug->IsEffectDefault() ? BUILTIN_EFFECT : PLUGIN_EFFECT;
|
||||
|
||||
OnEffect(type, pluginID);
|
||||
}
|
||||
|
||||
// Warning...complete hackage ahead
|
||||
void AudacityProject::OnEffect(const PluginID & pluginID, bool configured)
|
||||
{
|
||||
PluginManager & pm = PluginManager::Get();
|
||||
const PluginDescriptor *plug = pm.GetPlugin(pluginID);
|
||||
|
||||
int type;
|
||||
switch (plug->GetEffectType())
|
||||
{
|
||||
case EffectTypeGenerate:
|
||||
type = INSERT_EFFECT;
|
||||
break;
|
||||
|
||||
case EffectTypeProcess:
|
||||
type = PROCESS_EFFECT;
|
||||
break;
|
||||
|
||||
case EffectTypeAnalyze:
|
||||
type = ANALYZE_EFFECT;
|
||||
break;
|
||||
|
||||
case EffectTypeNone:
|
||||
type = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
type |= plug->IsEffectDefault() ? BUILTIN_EFFECT : PLUGIN_EFFECT;
|
||||
type |= configured ? CONFIGURED_EFFECT : 0;
|
||||
|
||||
OnStop();
|
||||
SelectAllIfNone();
|
||||
|
||||
OnEffect(type, pluginID);
|
||||
}
|
||||
|
||||
void AudacityProject::OnRepeatLastEffect(int WXUNUSED(index))
|
||||
{
|
||||
if (!mLastEffect.empty()) {
|
||||
// Setting the CONFIGURED_EFFECT bit prevents
|
||||
// prompting for parameters.
|
||||
OnEffect(mLastEffectType | CONFIGURED_EFFECT, mLastEffect);
|
||||
if (!mLastEffect.IsEmpty())
|
||||
{
|
||||
OnEffect(mLastEffect, OnEffectFlags::kConfigured);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EFFECT_CATEGORIES
|
||||
void AudacityProject::OnProcessAny(int index)
|
||||
{
|
||||
Effect* e = EffectManager::Get().GetEffect(index);
|
||||
OnEffect(ALL_EFFECTS, e);
|
||||
}
|
||||
#endif
|
||||
|
||||
void AudacityProject::OnStereoToMono(int WXUNUSED(index))
|
||||
{
|
||||
OnEffect(ALL_EFFECTS,
|
||||
EffectManager::Get().GetEffectByIdentifier(wxT("StereoToMono")));
|
||||
OnEffect(EffectManager::Get().GetEffectByIdentifier(wxT("StereoToMono")),
|
||||
OnEffectFlags::kConfigured);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -6359,53 +6085,6 @@ void AudacityProject::OnEditChains()
|
||||
dlg.ShowModal();
|
||||
}
|
||||
|
||||
wxString AudacityProject::BuildCleanFileName(wxString fileName, wxString extension)
|
||||
{
|
||||
wxFileName newFileName(fileName);
|
||||
wxString justName = newFileName.GetName();
|
||||
wxString pathName = newFileName.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
|
||||
|
||||
if (justName == wxT("")) {
|
||||
wxDateTime now = wxDateTime::Now();
|
||||
int year = now.GetYear();
|
||||
wxDateTime::Month month = now.GetMonth();
|
||||
wxString monthName = now.GetMonthName(month);
|
||||
int dom = now.GetDay();
|
||||
int hour = now.GetHour();
|
||||
int minute = now.GetMinute();
|
||||
int second = now.GetSecond();
|
||||
justName = wxString::Format(wxT("%d-%s-%02d-%02d-%02d-%02d"),
|
||||
year, monthName.c_str(), dom, hour, minute, second);
|
||||
|
||||
// SetName(cleanedFileName);
|
||||
// bool isStereo;
|
||||
// double endTime = project->mTracks->GetEndTime();
|
||||
// double startTime = 0.0;
|
||||
//OnSelectAll();
|
||||
pathName = gPrefs->Read(wxT("/DefaultOpenPath"), ::wxGetCwd());
|
||||
::wxMessageBox(wxString::Format(wxT("Export recording to %s\n/cleaned/%s%s"),
|
||||
pathName.c_str(), justName.c_str(), extension.c_str()),
|
||||
wxT("Export recording"),
|
||||
wxOK | wxCENTRE);
|
||||
pathName += wxT("/");
|
||||
}
|
||||
wxString cleanedName = pathName;
|
||||
cleanedName += wxT("cleaned");
|
||||
bool flag = ::wxFileName::FileExists(cleanedName);
|
||||
if (flag == true) {
|
||||
::wxMessageBox(wxT("Cannot create directory 'cleaned'. \nFile already exists that is not a directory"));
|
||||
return wxT("");
|
||||
}
|
||||
::wxFileName::Mkdir(cleanedName, 0777, wxPATH_MKDIR_FULL); // make sure it exists
|
||||
|
||||
cleanedName += wxT("/");
|
||||
cleanedName += justName;
|
||||
cleanedName += extension;
|
||||
wxGetApp().AddFileToHistory(cleanedName);
|
||||
|
||||
return cleanedName;
|
||||
}
|
||||
|
||||
void AudacityProject::OnRemoveTracks()
|
||||
{
|
||||
TrackListIterator iter(mTracks);
|
||||
|
||||
Reference in New Issue
Block a user