⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vsteffect.cpp

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************  Audacity: A Digital Audio Editor  VSTEffect.cpp  Dominic Mazzoni    This class implements a VST Plug-in effect.  The plug-in must be  loaded in a platform-specific way and passed into the constructor,  but from here this class handles the interfacing.  VST plug-ins  are used in Cubase and other Steinberg products, and all of those  files and the information within is copyrighted by Steinberg.**********************************************************************/#include "../../Audacity.h"#if USE_VST#include "AEffect.h"            // VST API#include "AEffEditor.hpp"#include <wx/defs.h>#include <wx/button.h>#include <wx/dialog.h>#include <wx/frame.h>#include <wx/slider.h>#include <wx/sizer.h>#include <wx/msgdlg.h>#include "../Effect.h"          // Audacity Effect base class#include "VSTEffect.h"          // This class's header file#ifdef __MACOSX__#include <Carbon/Carbon.h>#endifconst int VSTEFFECT_SLIDER_ID = 13100;const int PREVIEW_ID          = 13101;class VSTEffectGUIDialog : public wxDialog{public:   VSTEffectGUIDialog(wxWindow * parent, wxWindowID id,                      const wxString & title,                      VSTEffect *effect, AEffect *aEffect);   void OnOk(wxCommandEvent &event);   void OnCancel(wxCommandEvent &event);   void OnPreview(wxCommandEvent &event);   void OnIdle(wxIdleEvent &event);private:   VSTEffect *mEffect;   AEffect   *mAEffect;   DECLARE_EVENT_TABLE()};BEGIN_EVENT_TABLE(VSTEffectGUIDialog,wxDialog)   EVT_BUTTON( wxID_OK, VSTEffectGUIDialog::OnOk )   EVT_BUTTON( wxID_CANCEL, VSTEffectGUIDialog::OnCancel )   EVT_BUTTON( PREVIEW_ID, VSTEffectGUIDialog::OnPreview )   EVT_IDLE( VSTEffectGUIDialog::OnIdle )END_EVENT_TABLE()VSTEffectGUIDialog::VSTEffectGUIDialog(wxWindow *parent, wxWindowID id,                                       const wxString & title,                                       VSTEffect *effect,                                       AEffect *aEffect):   wxDialog(parent, id, title, wxDefaultPosition, wxDefaultSize,            wxRESIZE_BORDER | wxSYSTEM_MENU | wxCAPTION),   mEffect(effect),   mAEffect(aEffect){   ERect *rect;   mEffect->callDispatcher(mAEffect, effEditGetRect, 0, 0, &rect, 0.0);   mEffect->callDispatcher(mAEffect, effEditOpen, 0, 0, (void *)GetHWND(), 0.0);   wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);   mainSizer->Add(rect->right-rect->left, rect->bottom-rect->top);   wxBoxSizer *hSizer = new wxBoxSizer(wxHORIZONTAL);   wxButton *preview =      new wxButton(this, PREVIEW_ID, mEffect->GetPreviewName());   hSizer->Add(preview, 0, wxALIGN_CENTRE|wxALL, 5);   hSizer->Add(20, 10); // horizontal spacer   wxButton *cancel = new wxButton(this, wxID_CANCEL, _("Cancel"));   hSizer->Add(cancel, 0, wxALIGN_CENTRE|wxALL, 5);   wxButton *ok = new wxButton(this, wxID_OK, _("OK"));   ok->SetDefault();   ok->SetFocus();   hSizer->Add(ok, 0, wxALIGN_CENTRE|wxALL, 5);   mainSizer->Add(hSizer, 0, wxALIGN_CENTRE|wxALIGN_CENTER_VERTICAL|wxALL, 5);   SetAutoLayout(true);   SetSizer(mainSizer);   mainSizer->Fit(this);   mainSizer->SetSizeHints(this);}void VSTEffectGUIDialog::OnIdle(wxIdleEvent &event){   mEffect->callDispatcher(mAEffect, effEditIdle, 0, 0, NULL, 0.0);}void VSTEffectGUIDialog::OnPreview(wxCommandEvent &event){   mEffect->Preview();}void VSTEffectGUIDialog::OnOk(wxCommandEvent &event){   mEffect->callDispatcher(mAEffect, effEditClose, 0, 0, NULL, 0.0);   EndModal(true);}void VSTEffectGUIDialog::OnCancel(wxCommandEvent &event){   mEffect->callDispatcher(mAEffect, effEditClose, 0, 0, NULL, 0.0);   EndModal(false);}VSTEffect::VSTEffect(wxString pluginName, AEffect * aEffect){   this->aEffect = aEffect;   this->pluginName = pluginName;   buffer = NULL;   fInBuffer = NULL;   fOutBuffer = NULL;   isOpened = false;}VSTEffect::~VSTEffect(){}wxString VSTEffect::GetEffectName(){   return pluginName + "...";}wxString VSTEffect::GetEffectAction(){   return "Performing VST Effect: \""+pluginName+"\"";}bool VSTEffect::Init(){   inputs = aEffect->numInputs;   outputs = aEffect->numOutputs;   mBlockSize = 0;   if (inputs > 1) {      TrackListIterator iter(mWaveTracks);      Track *left = iter.First();      while(left) {         longSampleCount lstart, rstart;         sampleCount llen, rlen;         GetSamples((WaveTrack *)left, &lstart, &llen);                  if (left->GetLinked()) {            Track *right = iter.Next();            GetSamples((WaveTrack *)right, &rstart, &rlen);                        if (llen != rlen || ((WaveTrack *)left)->GetRate() != ((WaveTrack *)right)->GetRate()) {               wxMessageBox(_("Sorry, VST Effects cannot be performed on stereo tracks where "                            "the individual channels of the track do not match."));               return false;            }         }                  left = iter.Next();      }   }   return true;}bool VSTEffect::PromptUser(){   if (!(aEffect->flags & effFlagsCanReplacing)) {      wxMessageBox(_("Can't process replacing"));      return false;   }   if (aEffect->flags & effFlagsHasEditor) {      // Show native GUI      VSTEffectGUIDialog dlog(mParent, -1, pluginName, this, aEffect);      dlog.CentreOnParent();      dlog.ShowModal();      return dlog.GetReturnCode();   }   // Try to figure out how many parameters it takes by seeing how   // many parameters have names   char temp[8][256];   numParameters = 0;   do {      long result;      temp[numParameters][0] = 0;      result = callDispatcher(aEffect, effGetParamName, numParameters, 0,                              (void *) temp[numParameters], 0.0);      if (temp[numParameters][0]==0)         break;      if (strstr(temp[numParameters], "ABOUT"))         break;      if (numParameters > 0          && !strcmp(temp[numParameters], temp[numParameters - 1]))         break;      numParameters++;   } while (temp[0] != 0 && numParameters < 8);   if (numParameters > 0) {      VSTEffectDialog dlog(mParent, pluginName, numParameters, this, aEffect);      dlog.CentreOnParent();      dlog.ShowModal();      if (!dlog.GetReturnCode())         return false;   }   return true;}void VSTEffect::GetSamples(WaveTrack *track,                           longSampleCount *start,                           sampleCount *len){   double trackStart = track->GetStartTime();   double trackEnd = track->GetEndTime();   double t0 = mT0 < trackStart? trackStart: mT0;   double t1 = mT1 > trackEnd? trackEnd: mT1;      if (t1 > t0) {      *start = track->TimeToLongSamples(t0);      longSampleCount end = track->TimeToLongSamples(t1);      *len = (sampleCount)(end - *start);   }   else {      *start = 0;      *len  = 0;   }}bool VSTEffect::Process(){   TrackListIterator iter(mWaveTracks);   int count = 0;   Track *left = iter.First();   Track *right;   while(left) {      longSampleCount lstart, rstart;      sampleCount len;      GetSamples((WaveTrack *)left, &lstart, &len);      right = NULL;      if (left->GetLinked() && inputs>1) {         right = iter.Next();                  GetSamples((WaveTrack *)right, &rstart, &len);      }      // Reset the effect      callDispatcher(aEffect, effOpen, 0, 0, NULL, 0.0);            bool success = ProcessStereo(count,                                   (WaveTrack *)left, (WaveTrack *)right,                                   lstart, rstart, len);      if (!success)         return false;         left = iter.Next();      count++;   }      return true;}bool VSTEffect::ProcessStereo(int count, WaveTrack *left, WaveTrack *right,                              longSampleCount lstart,                              longSampleCount rstart, sampleCount len){   if (mBlockSize == 0) {      mBlockSize = left->GetMaxBlockSize() * 2;      buffer = new float[mBlockSize];      fInBuffer = new float *[inputs];      int i;      for (i = 0; i < inputs; i++)         fInBuffer[i] = new float[mBlockSize];      fOutBuffer = new float *[outputs];      for (i = 0; i < outputs; i++)         fOutBuffer[i] = new float[mBlockSize];   }   callDispatcher(aEffect, effSetSampleRate, 0, 0, NULL,                       (float) left->GetRate());   callDispatcher(aEffect, effSetBlockSize, 0, mBlockSize * 2, NULL, 0.0);   // Actually perform the effect here   sampleCount originalLen = len;   longSampleCount ls = lstart;   longSampleCount rs = rstart;   while (len) {      int i;      int block = mBlockSize;      if (block > len)         block = len;      left->Get((samplePtr)buffer, floatSample, ls, block);      for (i = 0; i < block; i++)         fInBuffer[0][i] = buffer[i];      if (right) {         right->Get((samplePtr)buffer, floatSample, rs, block);         for (i = 0; i < block; i++)            fInBuffer[1][i] = buffer[i];      }      callProcessReplacing(aEffect, fInBuffer, fOutBuffer, block);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -