Audacity  3.0.3
Public Member Functions | Static Public Member Functions | List of all members
VSTEffectsModule Class Referencefinal

#include <VSTEffect.h>

Inheritance diagram for VSTEffectsModule:
[legend]
Collaboration diagram for VSTEffectsModule:
[legend]

Public Member Functions

 VSTEffectsModule ()
 
virtual ~VSTEffectsModule ()
 
PluginPath GetPath () override
 
ComponentInterfaceSymbol GetSymbol () override
 
VendorSymbol GetVendor () override
 
wxString GetVersion () override
 
TranslatableString GetDescription () override
 
bool Initialize () override
 
void Terminate () override
 
EffectFamilySymbol GetOptionalFamilySymbol () override
 
const FileExtensionsGetFileExtensions () override
 
FilePath InstallPath () override
 
bool AutoRegisterPlugins (PluginManagerInterface &pm) override
 
PluginPaths FindPluginPaths (PluginManagerInterface &pm) override
 
unsigned DiscoverPluginsAtPath (const PluginPath &path, TranslatableString &errMsg, const RegistrationCallback &callback) override
 
bool IsPluginValid (const PluginPath &path, bool bFast) override
 
std::unique_ptr< ComponentInterfaceCreateInstance (const PluginPath &path) override
 
- Public Member Functions inherited from ModuleInterface
virtual ~ModuleInterface ()
 
- Public Member Functions inherited from ComponentInterface
virtual ~ComponentInterface ()
 
TranslatableString GetName ()
 
virtual bool DefineParams (ShuttleParams &WXUNUSED(S))
 

Static Public Member Functions

static void Check (const wxChar *path)
 

Additional Inherited Members

- Public Types inherited from ModuleInterface
using RegistrationCallback = std::function< const PluginID &(ModuleInterface *, ComponentInterface *) >
 

Detailed Description

VSTEffectsModule is an Audacity ModuleInterface, in other words it represents one plug in.

Definition at line 403 of file VSTEffect.h.

Constructor & Destructor Documentation

◆ VSTEffectsModule()

VSTEffectsModule::VSTEffectsModule ( )

Definition at line 311 of file VSTEffect.cpp.

312 {
313 }

◆ ~VSTEffectsModule()

VSTEffectsModule::~VSTEffectsModule ( )
virtual

Definition at line 315 of file VSTEffect.cpp.

316 {
317 }

Member Function Documentation

◆ AutoRegisterPlugins()

bool VSTEffectsModule::AutoRegisterPlugins ( PluginManagerInterface pm)
overridevirtual

Implements ModuleInterface.

Definition at line 388 of file VSTEffect.cpp.

389 {
390  // We don't auto-register
391  return true;
392 }

◆ Check()

void VSTEffectsModule::Check ( const wxChar *  path)
static

Definition at line 708 of file VSTEffect.cpp.

709 {
710  VSTEffect effect(path);
711  if (effect.SetHost(NULL))
712  {
713  auto effectIDs = effect.GetEffectIDs();
714  wxString out;
715 
716  if (effectIDs.size() > 0)
717  {
718  wxString subids;
719 
720  for (size_t i = 0, cnt = effectIDs.size(); i < cnt; i++)
721  {
722  subids += wxString::Format(wxT("%d;"), effectIDs[i]);
723  }
724 
725  out = wxString::Format(wxT("%s%d=%s\n"), OUTPUTKEY, kKeySubIDs, subids.RemoveLast());
726  }
727  else
728  {
729  out += wxString::Format(wxT("%s%d=%s\n"), OUTPUTKEY, kKeyBegin, wxEmptyString);
730  out += wxString::Format(wxT("%s%d=%s\n"), OUTPUTKEY, kKeyPath, effect.GetPath());
731  out += wxString::Format(wxT("%s%d=%s\n"), OUTPUTKEY, kKeyName, effect.GetSymbol().Internal());
732  out += wxString::Format(wxT("%s%d=%s\n"), OUTPUTKEY, kKeyVendor,
733  effect.GetVendor().Internal());
734  out += wxString::Format(wxT("%s%d=%s\n"), OUTPUTKEY, kKeyVersion, effect.GetVersion());
735  out += wxString::Format(wxT("%s%d=%s\n"), OUTPUTKEY, kKeyDescription, effect.GetDescription().Translation());
736  out += wxString::Format(wxT("%s%d=%d\n"), OUTPUTKEY, kKeyEffectType, effect.GetType());
737  out += wxString::Format(wxT("%s%d=%d\n"), OUTPUTKEY, kKeyInteractive, effect.IsInteractive());
738  out += wxString::Format(wxT("%s%d=%d\n"), OUTPUTKEY, kKeyAutomatable, effect.SupportsAutomation());
739  out += wxString::Format(wxT("%s%d=%s\n"), OUTPUTKEY, kKeyEnd, wxEmptyString);
740  }
741 
742  // We want to output info in one chunk to prevent output
743  // from the effect intermixing with the info
744  const wxCharBuffer buf = out.ToUTF8();
745  fwrite(buf, 1, strlen(buf), stdout);
746  fflush(stdout);
747  }
748 }

References VSTEffect::GetDescription(), VSTEffect::GetEffectIDs(), VSTEffect::GetPath(), VSTEffect::GetSymbol(), VSTEffect::GetType(), VSTEffect::GetVendor(), VSTEffect::GetVersion(), ComponentInterfaceSymbol::Internal(), VSTEffect::IsInteractive(), kKeyAutomatable, kKeyBegin, kKeyDescription, kKeyEffectType, kKeyEnd, kKeyInteractive, kKeyName, kKeyPath, kKeySubIDs, kKeyVendor, kKeyVersion, OUTPUTKEY, VSTEffect::SetHost(), VSTEffect::SupportsAutomation(), and TranslatableString::Translation().

Referenced by VSTSubEntry::OnInit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CreateInstance()

std::unique_ptr< ComponentInterface > VSTEffectsModule::CreateInstance ( const PluginPath path)
overridevirtual

Implements ModuleInterface.

Definition at line 690 of file VSTEffect.cpp.

691 {
692  // Acquires a resource for the application.
693  // For us, the ID is simply the path to the effect
694  return std::make_unique<VSTEffect>(path);
695 }

◆ DiscoverPluginsAtPath()

unsigned VSTEffectsModule::DiscoverPluginsAtPath ( const PluginPath path,
TranslatableString errMsg,
const RegistrationCallback callback 
)
overridevirtual

Implements ModuleInterface.

Definition at line 503 of file VSTEffect.cpp.

506 {
507  bool error = false;
508  unsigned nFound = 0;
509  errMsg = {};
510  // TODO: Fix this for external usage
511  const auto &cmdpath = PlatformCompatibility::GetExecutablePath();
512 
513  wxString effectIDs = wxT("0;");
514  wxStringTokenizer effectTzr(effectIDs, wxT(";"));
515 
516  Optional<ProgressDialog> progress{};
517  size_t idCnt = 0;
518  size_t idNdx = 0;
519 
520  bool cont = true;
521 
522  while (effectTzr.HasMoreTokens() && cont)
523  {
524  wxString effectID = effectTzr.GetNextToken();
525 
526  wxString cmd;
527  cmd.Printf(wxT("\"%s\" %s \"%s;%s\""), cmdpath, VSTCMDKEY, path, effectID);
528 
529  VSTSubProcess proc;
530  try
531  {
532  int flags = wxEXEC_SYNC | wxEXEC_NODISABLE;
533 #if defined(__WXMSW__)
534  flags += wxEXEC_NOHIDE;
535 #endif
536  wxExecute(cmd, flags, &proc);
537  }
538  catch (...)
539  {
540  wxLogMessage(wxT("VST plugin registration failed for %s\n"), path);
541  error = true;
542  }
543 
544  wxString output;
545  wxStringOutputStream ss(&output);
546  proc.GetInputStream()->Read(ss);
547 
548  int keycount = 0;
549  bool haveBegin = false;
550  wxStringTokenizer tzr(output, wxT("\n"));
551  while (tzr.HasMoreTokens())
552  {
553  wxString line = tzr.GetNextToken();
554 
555  // Our output may follow any output the plugin may have written.
556  if (!line.StartsWith(OUTPUTKEY))
557  {
558  continue;
559  }
560 
561  long key;
562  if (!line.Mid(wxStrlen(OUTPUTKEY)).BeforeFirst(wxT('=')).ToLong(&key))
563  {
564  continue;
565  }
566  wxString val = line.AfterFirst(wxT('=')).BeforeFirst(wxT('\r'));
567 
568  switch (key)
569  {
570  case kKeySubIDs:
571  effectIDs = val;
572  effectTzr.Reinit(effectIDs);
573  idCnt = effectTzr.CountTokens();
574  if (idCnt > 3)
575  {
576  progress.emplace( XO("Scanning Shell VST"),
577  XO("Registering %d of %d: %-64.64s")
578  .Format( 0, idCnt, proc.GetSymbol().Translation())
579  /*
580  , wxPD_APP_MODAL |
581  wxPD_AUTO_HIDE |
582  wxPD_CAN_ABORT |
583  wxPD_ELAPSED_TIME |
584  wxPD_ESTIMATED_TIME |
585  wxPD_REMAINING_TIME
586  */
587  );
588  progress->Show();
589  }
590  break;
591 
592  case kKeyBegin:
593  haveBegin = true;
594  keycount++;
595  break;
596 
597  case kKeyName:
598  proc.mName = val;
599  keycount++;
600  break;
601 
602  case kKeyPath:
603  proc.mPath = val;
604  keycount++;
605  break;
606 
607  case kKeyVendor:
608  proc.mVendor = val;
609  keycount++;
610  break;
611 
612  case kKeyVersion:
613  proc.mVersion = val;
614  keycount++;
615  break;
616 
617  case kKeyDescription:
618  proc.mDescription = Verbatim( val );
619  keycount++;
620  break;
621 
622  case kKeyEffectType:
623  long type;
624  val.ToLong(&type);
625  proc.mType = (EffectType) type;
626  keycount++;
627  break;
628 
629  case kKeyInteractive:
630  proc.mInteractive = val == wxT("1");
631  keycount++;
632  break;
633 
634  case kKeyAutomatable:
635  proc.mAutomatable = val == wxT("1");
636  keycount++;
637  break;
638 
639  case kKeyEnd:
640  {
641  if (!haveBegin || ++keycount != kKeyEnd)
642  {
643  keycount = 0;
644  haveBegin = false;
645  continue;
646  }
647 
648  bool skip = false;
649  if (progress)
650  {
651  idNdx++;
652  auto result = progress->Update((int)idNdx, (int)idCnt,
653  XO("Registering %d of %d: %-64.64s")
654  .Format( idNdx, idCnt, proc.GetSymbol().Translation() ));
655  cont = (result == ProgressResult::Success);
656  }
657 
658  if (!skip && cont)
659  {
660  if (callback)
661  callback( this, &proc );
662  ++nFound;
663  }
664  }
665  break;
666 
667  default:
668  keycount = 0;
669  haveBegin = false;
670  break;
671  }
672  }
673  }
674 
675  if (error)
676  errMsg = XO("Could not load the library");
677 
678  return nFound;
679 }

References PlatformCompatibility::GetExecutablePath(), VSTSubProcess::GetSymbol(), key, kKeyAutomatable, kKeyBegin, kKeyDescription, kKeyEffectType, kKeyEnd, kKeyInteractive, kKeyName, kKeyPath, kKeySubIDs, kKeyVendor, kKeyVersion, VSTSubProcess::mAutomatable, VSTSubProcess::mDescription, VSTSubProcess::mInteractive, VSTSubProcess::mName, VSTSubProcess::mPath, VSTSubProcess::mType, VSTSubProcess::mVendor, VSTSubProcess::mVersion, OUTPUTKEY, BasicUI::Success, ComponentInterfaceSymbol::Translation(), Verbatim(), VSTCMDKEY, and XO.

Here is the call graph for this function:

◆ FindPluginPaths()

PluginPaths VSTEffectsModule::FindPluginPaths ( PluginManagerInterface pm)
overridevirtual

Implements ModuleInterface.

Definition at line 394 of file VSTEffect.cpp.

395 {
396  FilePaths pathList;
397  FilePaths files;
398 
399  // Check for the VST_PATH environment variable
400  wxString vstpath = wxString::FromUTF8(getenv("VST_PATH"));
401  if (!vstpath.empty())
402  {
403  wxStringTokenizer tok(vstpath, wxPATH_SEP);
404  while (tok.HasMoreTokens())
405  {
406  pathList.push_back(tok.GetNextToken());
407  }
408  }
409 
410 #if defined(__WXMAC__)
411 #define VSTPATH wxT("/Library/Audio/Plug-Ins/VST")
412 
413  // Look in ~/Library/Audio/Plug-Ins/VST and /Library/Audio/Plug-Ins/VST
414  pathList.push_back(wxGetHomeDir() + wxFILE_SEP_PATH + VSTPATH);
415  pathList.push_back(VSTPATH);
416 
417  // Recursively search all paths for Info.plist files. This will identify all
418  // bundles.
419  pm.FindFilesInPathList(wxT("Info.plist"), pathList, files, true);
420 
421  // Remove the 'Contents/Info.plist' portion of the names
422  for (size_t i = 0; i < files.size(); i++)
423  {
424  files[i] = wxPathOnly(wxPathOnly(files[i]));
425  if (!files[i].EndsWith(wxT(".vst")))
426  {
427  files.erase( files.begin() + i-- );
428  }
429  }
430 
431 #elif defined(__WXMSW__)
432 
433  TCHAR dpath[MAX_PATH];
434  TCHAR tpath[MAX_PATH];
435  DWORD len;
436 
437  // Try HKEY_CURRENT_USER registry key first
438  len = WXSIZEOF(tpath);
439  if (SHRegGetUSValue(wxT("Software\\VST"),
440  wxT("VSTPluginsPath"),
441  NULL,
442  tpath,
443  &len,
444  FALSE,
445  NULL,
446  0) == ERROR_SUCCESS)
447  {
448  tpath[len] = 0;
449  dpath[0] = 0;
450  ExpandEnvironmentStrings(tpath, dpath, WXSIZEOF(dpath));
451  pathList.push_back(dpath);
452  }
453 
454  // Then try HKEY_LOCAL_MACHINE registry key
455  len = WXSIZEOF(tpath);
456  if (SHRegGetUSValue(wxT("Software\\VST"),
457  wxT("VSTPluginsPath"),
458  NULL,
459  tpath,
460  &len,
461  TRUE,
462  NULL,
463  0) == ERROR_SUCCESS)
464  {
465  tpath[len] = 0;
466  dpath[0] = 0;
467  ExpandEnvironmentStrings(tpath, dpath, WXSIZEOF(dpath));
468  pathList.push_back(dpath);
469  }
470 
471  // Add the default path last
472  dpath[0] = 0;
473  ExpandEnvironmentStrings(wxT("%ProgramFiles%\\Steinberg\\VSTPlugins"),
474  dpath,
475  WXSIZEOF(dpath));
476  pathList.push_back(dpath);
477 
478  // Recursively scan for all DLLs
479  pm.FindFilesInPathList(wxT("*.dll"), pathList, files, true);
480 
481 #else
482 
483  // Nothing specified in the VST_PATH environment variable...provide defaults
484  if (vstpath.empty())
485  {
486  // We add this "non-default" one
487  pathList.push_back(wxT(LIBDIR) wxT("/vst"));
488 
489  // These are the defaults used by other hosts
490  pathList.push_back(wxT("/usr/lib/vst"));
491  pathList.push_back(wxT("/usr/local/lib/vst"));
492  pathList.push_back(wxGetHomeDir() + wxFILE_SEP_PATH + wxT(".vst"));
493  }
494 
495  // Recursively scan for all shared objects
496  pm.FindFilesInPathList(wxT("*.so"), pathList, files, true);
497 
498 #endif
499 
500  return { files.begin(), files.end() };
501 }

References PluginManagerInterface::FindFilesInPathList().

Here is the call graph for this function:

◆ GetDescription()

TranslatableString VSTEffectsModule::GetDescription ( )
overridevirtual

Implements ComponentInterface.

Definition at line 344 of file VSTEffect.cpp.

345 {
346  return XO("Adds the ability to use VST effects in Audacity.");
347 }

References XO.

◆ GetFileExtensions()

const FileExtensions & VSTEffectsModule::GetFileExtensions ( )
overridevirtual

Implements ModuleInterface.

Definition at line 374 of file VSTEffect.cpp.

375 {
376  static FileExtensions result{{ _T("vst") }};
377  return result;
378 }

◆ GetOptionalFamilySymbol()

EffectFamilySymbol VSTEffectsModule::GetOptionalFamilySymbol ( )
overridevirtual

Implements ModuleInterface.

Definition at line 365 of file VSTEffect.cpp.

366 {
367 #if USE_VST
368  return VSTPLUGINTYPE;
369 #else
370  return {};
371 #endif
372 }

References VSTPLUGINTYPE.

◆ GetPath()

PluginPath VSTEffectsModule::GetPath ( )
overridevirtual

Implements ComponentInterface.

Definition at line 323 of file VSTEffect.cpp.

324 {
325  return {};
326 }

◆ GetSymbol()

ComponentInterfaceSymbol VSTEffectsModule::GetSymbol ( )
overridevirtual

Implements ComponentInterface.

Definition at line 328 of file VSTEffect.cpp.

329 {
330  return XO("VST Effects");
331 }

References XO.

◆ GetVendor()

VendorSymbol VSTEffectsModule::GetVendor ( )
overridevirtual

Implements ComponentInterface.

Definition at line 333 of file VSTEffect.cpp.

334 {
335  return XO("The Audacity Team");
336 }

References XO.

◆ GetVersion()

wxString VSTEffectsModule::GetVersion ( )
overridevirtual

Implements ComponentInterface.

Definition at line 338 of file VSTEffect.cpp.

339 {
340  // This "may" be different if this were to be maintained as a separate DLL
341  return AUDACITY_VERSION_STRING;
342 }

◆ Initialize()

bool VSTEffectsModule::Initialize ( )
overridevirtual

Implements ModuleInterface.

Definition at line 353 of file VSTEffect.cpp.

354 {
355  // Nothing to do here
356  return true;
357 }

◆ InstallPath()

FilePath VSTEffectsModule::InstallPath ( )
overridevirtual

Implements ModuleInterface.

Definition at line 380 of file VSTEffect.cpp.

381 {
382  // Not yet ready for VST drag-and-drop...
383  // return FileNames::PlugInDir();
384 
385  return {};
386 }

◆ IsPluginValid()

bool VSTEffectsModule::IsPluginValid ( const PluginPath path,
bool  bFast 
)
overridevirtual

Implements ModuleInterface.

Definition at line 681 of file VSTEffect.cpp.

682 {
683  if( bFast )
684  return true;
685  wxString realPath = path.BeforeFirst(wxT(';'));
686  return wxFileName::FileExists(realPath) || wxFileName::DirExists(realPath);
687 }

◆ Terminate()

void VSTEffectsModule::Terminate ( )
overridevirtual

Implements ModuleInterface.

Definition at line 359 of file VSTEffect.cpp.

360 {
361  // Nothing to do here
362  return;
363 }

The documentation for this class was generated from the following files:
BasicUI::ProgressResult::Success
@ Success
Optional
Like a smart pointer, allows for object to not exist (nullptr)
Definition: MemoryX.h:144
kKeyInteractive
@ kKeyInteractive
Definition: VSTEffect.cpp:213
kKeyAutomatable
@ kKeyAutomatable
Definition: VSTEffect.cpp:214
ComponentInterfaceSymbol::Translation
const wxString Translation() const
Definition: ComponentInterfaceSymbol.h:58
kKeySubIDs
@ kKeySubIDs
Definition: VSTEffect.cpp:205
Format
Abstract base class used in importing a file.
XO
#define XO(s)
Definition: Internat.h:31
VSTSubProcess::mDescription
TranslatableString mDescription
Definition: VSTEffect.cpp:300
VSTCMDKEY
#define VSTCMDKEY
Definition: VSTEffect.h:31
kKeyName
@ kKeyName
Definition: VSTEffect.cpp:207
wxArrayStringEx
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
Definition: wxArrayStringEx.h:18
VSTSubProcess::mName
wxString mName
Definition: VSTEffect.cpp:297
kKeyPath
@ kKeyPath
Definition: VSTEffect.cpp:208
VSTSubProcess::mVersion
wxString mVersion
Definition: VSTEffect.cpp:299
kKeyEffectType
@ kKeyEffectType
Definition: VSTEffect.cpp:212
PluginManagerInterface::FindFilesInPathList
virtual void FindFilesInPathList(const wxString &pattern, const FilePaths &pathList, FilePaths &files, bool directories=false)=0
kKeyDescription
@ kKeyDescription
Definition: VSTEffect.cpp:211
kKeyEnd
@ kKeyEnd
Definition: VSTEffect.cpp:215
VSTSubProcess::mType
EffectType mType
Definition: VSTEffect.cpp:301
kKeyBegin
@ kKeyBegin
Definition: VSTEffect.cpp:206
VSTSubProcess::GetSymbol
ComponentInterfaceSymbol GetSymbol() override
Definition: VSTEffect.cpp:240
key
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: CommandManager.cpp:201
VSTSubProcess
Definition: VSTEffect.cpp:226
OUTPUTKEY
#define OUTPUTKEY
Definition: VSTEffect.cpp:202
VSTEffect
Definition: VSTEffect.h:97
Verbatim
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
Definition: TranslatableString.h:321
kKeyVendor
@ kKeyVendor
Definition: VSTEffect.cpp:209
kKeyVersion
@ kKeyVersion
Definition: VSTEffect.cpp:210
VSTPLUGINTYPE
#define VSTPLUGINTYPE
Definition: VSTEffect.h:34
VSTSubProcess::mPath
wxString mPath
Definition: VSTEffect.cpp:296
EffectType
EffectType
Definition: EffectInterface.h:55
VSTSubProcess::mInteractive
bool mInteractive
Definition: VSTEffect.cpp:302
PlatformCompatibility::GetExecutablePath
static const FilePath & GetExecutablePath()
Definition: PlatformCompatibility.cpp:33
VSTSubProcess::mVendor
wxString mVendor
Definition: VSTEffect.cpp:298
VSTSubProcess::mAutomatable
bool mAutomatable
Definition: VSTEffect.cpp:303