Update of /cvsroot/audacity/audacity-src/src/effects/vamp
In directory sc8-pr-cvs11.sourceforge.net:/tmp/cvs-serv7464/src/effects/vamp

Added Files:
        LoadVamp.cpp LoadVamp.h VampEffect.cpp VampEffect.h 
Log Message:
-Progressed Checklist.

--- NEW FILE: LoadVamp.h ---
/**********************************************************************

  Audacity: A Digital Audio Editor

  LoadVamp.h

  Chris Cannam

**********************************************************************/

void LoadVampPlugins();

// Indentation settings for Vim and Emacs and unique identifier for Arch, a
// version control system. Please do not modify past this point.
//
// Local Variables:
// c-basic-offset: 3
// indent-tabs-mode: nil
// End:
//
// vim: et sts=3 sw=3
// arch-tag: 21a6d3fe-1003-4cec-a44c-4a16335b5cda

--- NEW FILE: VampEffect.cpp ---
/**********************************************************************

  Audacity: A Digital Audio Editor

  VampEffect.cpp

  Chris Cannam, with heavy borrowing from LadspaEffect.cpp

  Vamp is an audio analysis and feature extraction plugin API.
  http://www.vamp-plugins.org/

**********************************************************************/

#include "VampEffect.h"

//#include <vamp-sdk/Plugin.h>
//#include <vamp-sdk/hostext/PluginChannelAdapter.h>
//#include <vamp-sdk/hostext/PluginInputDomainAdapter.h>
#include "../../../lib-src/libvamp/vamp-sdk/Plugin.h"
#include "../../../lib-src/libvamp/vamp-sdk/hostext/PluginChannelAdapter.h"
#include "../../../lib-src/libvamp/vamp-sdk/hostext/PluginInputDomainAdapter.h"

#include <wx/wxprec.h>
#include <wx/button.h>
#include <wx/checkbox.h>
#include <wx/combobox.h>
#include <wx/msgdlg.h>
#include <wx/sizer.h>
#include <wx/slider.h>
#include <wx/statbox.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/tokenzr.h>
#include <wx/intl.h>
#include <wx/scrolwin.h>

VampEffect::VampEffect(Vamp::HostExt::PluginLoader::PluginKey key,
                       int output,
                       bool hasParameters,
                       wxString name) :
   mKey(key),
   mOutput(output),
   mHasParameters(hasParameters),
   mName(name),
   mRate(0),
   mPlugin(0)
{
}

VampEffect::~VampEffect()
{
   delete mPlugin;
   mPlugin = 0;
}

wxString VampEffect::GetEffectName()
{
   if (mHasParameters) {
      return mName + LAT1CTOWX("...");
   } else {
      return mName;
   }
}

wxString VampEffect::GetEffectIdentifier()
{
   return LAT1CTOWX(mKey.c_str());
}

wxString VampEffect::GetEffectAction()
{
   return wxString::Format(_("Extracting features: %s"),
                           GetEffectName().c_str());
}

int VampEffect::GetEffectFlags()
{
   return PLUGIN_EFFECT | ANALYZE_EFFECT;
}

bool VampEffect::Init()
{
   Vamp::HostExt::PluginLoader *loader =
      Vamp::HostExt::PluginLoader::getInstance();
   
   delete mPlugin;
   mPlugin = 0;

   TrackListIterator iter(mWaveTracks);
   WaveTrack *left = (WaveTrack *)iter.First();

   mRate = 0.0;

   while (left) {

      if (mRate == 0.0) mRate = left->GetRate();
      
      if (left->GetLinked()) {

         WaveTrack *right = (WaveTrack *)iter.Next();
         
         if (left->GetRate() != right->GetRate()) {
            wxMessageBox(_("Sorry, Vamp Plug-ins cannot be run on stereo tracks 
where the individual channels of he track do not match."));
            return false;
         }
      }
      
      left = (WaveTrack *)iter.Next();
   }

   if (mRate <= 0.0) mRate = mProjectRate;

   mPlugin = loader->loadPlugin
      (mKey, mRate, Vamp::HostExt::PluginLoader::ADAPT_ALL);

   if (!mPlugin) {
      wxMessageBox(_("Sorry, failed to load Vamp Plug-in."));
      return false;
   }

   return true;
}

bool VampEffect::PromptUser()
{
   if (!mPlugin) return false;
   if (!mHasParameters) return true;

   VampEffectDialog dlog(this, mParent, mPlugin);
   dlog.CentreOnParent();
   dlog.ShowModal();

   if (!dlog.GetReturnCode()) return false;

   return true;
}

void VampEffect::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 VampEffect::Process()
{
   if (!mPlugin) return false;

   TrackListIterator iter(mWaveTracks);

   int count = 0;

   WaveTrack *left = (WaveTrack *)iter.First();

   bool multiple = false;
   int prevTrackChannels = 0;

   TrackListIterator scooter(iter);
   if (left->GetLinked()) scooter.Next();      
   if (scooter.Next()) {
      // if there is another track beyond this one and any linked one,
      // then we're processing more than one track.  That means we
      // should use the originating track name in each new label
      // track's name, to make clear which is which
      multiple = true;
   }

   while (left) {

      longSampleCount lstart, rstart;
      sampleCount len;
      GetSamples(left, &lstart, &len);
      
      WaveTrack *right = NULL;
      int channels = 1;

      if (left->GetLinked()) {
         right = (WaveTrack *)iter.Next();
         channels = 2;
         GetSamples(right, &rstart, &len);
      }

      size_t step = mPlugin->getPreferredStepSize();
      size_t block = mPlugin->getPreferredBlockSize();

      bool initialiseRequired = true;

      if (prevTrackChannels > 0) {
         // Plugin has already been initialised, so if the number of
         // channels remains the same, we only need to do a reset.
         // Otherwise we need to re-construct the whole plugin,
         // because a Vamp plugin can't be re-initialised.
         if (prevTrackChannels == channels) {
            mPlugin->reset();
            initialiseRequired = false;
         } else {
            Init();
         }
      }

      if (initialiseRequired) {
         if (!mPlugin->initialise(channels, step, block)) {
            wxMessageBox(_("Sorry, Vamp Plug-in failed to initialize."));
            return false;
         }
      }

      LabelTrack *ltrack = mFactory->NewLabelTrack();

      if (!multiple) {
         ltrack->SetName(GetEffectName());
      } else {
         ltrack->SetName(wxString::Format(_("%s: %s"),
                                          left->GetName().c_str(),
                                          GetEffectName().c_str()));
      }

      mTracks->Add(ltrack);

      float **data = new float*[channels];
      for (int c = 0; c < channels; ++c) data[c] = new float[block];

      sampleCount originalLen = len;
      longSampleCount ls = lstart;
      longSampleCount rs = rstart;

      while (len) {
         
         int request = block;
         if (request > len) request = len;

         if (left) left->Get((samplePtr)data[0], floatSample, ls, request);
         if (right) right->Get((samplePtr)data[1], floatSample, rs, request);

         if (request < block) {
            for (int c = 0; c < channels; ++c) {
               for (int i = request; i < block; ++i) {
                  data[c][i] = 0.f;
               }
            }
         }

         Vamp::RealTime timestamp = Vamp::RealTime::frame2RealTime
            (ls, (int)(mRate + 0.5));

         Vamp::Plugin::FeatureSet features = mPlugin->process(data, timestamp);
         AddFeatures(ltrack, features);

         if (len > step) len -= step;
         else len = 0;

         ls += step;
         rs += step;

         if (channels > 1) {
            if (TrackGroupProgress(count, (ls - lstart) / double(originalLen)))
               return false;
         } else {
            if (TrackProgress(count, (ls - lstart) / double(originalLen)))
               return false;
         }
      }

      Vamp::Plugin::FeatureSet features = mPlugin->getRemainingFeatures();
      AddFeatures(ltrack, features);

      left = (WaveTrack *)iter.Next();
   }

   return true;
}

void VampEffect::AddFeatures(LabelTrack *ltrack,
                             Vamp::Plugin::FeatureSet &features)
{
   for (Vamp::Plugin::FeatureList::iterator fli = features[mOutput].begin();
        fli != features[mOutput].end(); ++fli) {
      
      Vamp::RealTime ftime = fli->timestamp;
      double ltime = ftime.sec + (double(ftime.nsec) / 1000000000.0);

      wxString label = LAT1CTOWX(fli->label.c_str());
      if (label == wxString()) {
         label = wxString::Format(LAT1CTOWX("%.3f"), ltime);
      }
      
      ltrack->AddLabel(ltime, ltime, label);
   }
}

void VampEffect::End()
{
   delete mPlugin;
   mPlugin = 0;
}


BEGIN_EVENT_TABLE(VampEffectDialog, wxDialog)
    EVT_BUTTON(wxID_OK, VampEffectDialog::OnOK)
    EVT_BUTTON(wxID_CANCEL, VampEffectDialog::OnCancel)
    EVT_SLIDER(wxID_ANY, VampEffectDialog::OnSlider)
    EVT_TEXT(wxID_ANY, VampEffectDialog::OnTextCtrl)
    EVT_CHECKBOX(wxID_ANY, VampEffectDialog::OnCheckBox)
    EVT_COMBOBOX(wxID_ANY, VampEffectDialog::OnComboBox)
END_EVENT_TABLE()

IMPLEMENT_CLASS(VampEffectDialog, wxDialog)

VampEffectDialog::VampEffectDialog(VampEffect *effect,
                                   wxWindow *parent,
                                   Vamp::Plugin *plugin) :
   wxDialog(parent, -1, effect->GetEffectName(),
            wxDefaultPosition, wxDefaultSize,
            wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
   mEffect(effect),
   mPlugin(plugin)
{
   Vamp::Plugin::ProgramList programs = plugin->getPrograms();

   mParameters = plugin->getParameterDescriptors();

#ifdef __WXMSW__
   // On Windows, for some reason, wxWindows calls OnTextCtrl during creation
   // of the text control, and VampEffectDialog::OnTextCtrl calls HandleText, 
   // which assumes all the fields have been initialized. 
   // This can give us a bad pointer crash, so manipulate inSlider to 
   // no-op HandleText during creation.
   inSlider = true;
#else
   inSlider = false;
#endif

   inText = false;
   
   int count = mParameters.size();

   toggles = new wxCheckBox*[count];
   sliders = new wxSlider*[count];
   fields = new wxTextCtrl*[count];
   labels = new wxStaticText*[count];
   combos = new wxComboBox*[count];

   wxControl *item;

   wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL);

   item = new wxStaticText(this, 0,
                           LAT1CTOWX(plugin->getName().c_str()) +
                           wxString(_(" - Vamp audio analysis plugin")));
   vSizer->Add(item, 0, wxALL, 5);

   item = new wxStaticText(this, 0,
                           LAT1CTOWX(plugin->getDescription().c_str()));
   vSizer->Add(item, 0, wxALL, 5);

   item = new wxStaticText(this, 0,
                           wxString(_("Author: "))
                           + LAT1CTOWX(plugin->getMaker().c_str()));

   vSizer->Add(item, 0, wxALL, 5);
   
   item = new wxStaticText(this, 0,
                           LAT1CTOWX(plugin->getCopyright().c_str()));
   vSizer->Add(item, 0, wxALL, 5);

   wxScrolledWindow *w = new wxScrolledWindow(this,
                                              wxID_ANY,
                                              wxDefaultPosition,
                                              wxDefaultSize,
                                              wxVSCROLL | wxTAB_TRAVERSAL);

   // Try to give the window a sensible default/minimum size
   w->SetMinSize(wxSize(
      wxMax(400, parent->GetSize().GetWidth() / 2),
      parent->GetSize().GetHeight() / 2));
                                              
   w->SetScrollRate(0, 20);
   vSizer->Add(w, 1, wxEXPAND|wxALL, 5);

   wxBoxSizer *okSizer = new wxBoxSizer(wxHORIZONTAL);

   wxButton *button;

   button = new wxButton(this, wxID_CANCEL, _("&Cancel"));
   okSizer->Add(button, 0, wxALIGN_CENTRE | wxALL, 5);

   button = new wxButton(this, wxID_OK, _("&OK"));
   button->SetDefault();
   okSizer->Add(button, 0, wxALIGN_CENTRE | wxALL, 5);

   vSizer->Add(okSizer, 0, wxALIGN_CENTRE | wxALL, 5);

   SetSizer(vSizer);

   wxSizer *paramSizer =
      new wxStaticBoxSizer(wxVERTICAL, w, _("Plugin Settings"));

   wxFlexGridSizer *gridSizer = new wxFlexGridSizer(5, 0, 0);
   gridSizer->AddGrowableCol(3);

   programCombo = 0;

   if (!programs.empty()) {

      wxArrayString choices;
      wxString currentProgram =
         wxString(mPlugin->getCurrentProgram().c_str(), wxConvISO8859_1);

      for (size_t i = 0; i < programs.size(); ++i) {

         wxString choice = wxString(programs[i].c_str(), wxConvISO8859_1);
         choices.Add(choice);
      }

      programCombo = new wxComboBox(w, 9999, currentProgram,
                                    wxDefaultPosition, wxDefaultSize,
                                    choices, wxCB_READONLY);

      gridSizer->Add(new wxStaticText(w, 0, _("Program")), 
                     0, wxALIGN_CENTER_VERTICAL | wxALL, 5);

      gridSizer->Add(1, 1, 0);
      gridSizer->Add(1, 1, 0);

      gridSizer->Add(programCombo, 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | 
wxALL, 5);
      ConnectFocus(programCombo);

      gridSizer->Add(1, 1, 0);
   }

   for (int p = 0; p < count; p++) {

      item = new wxStaticText(w, 0, wxString(mParameters[p].name.c_str(),
                                             wxConvISO8859_1));
      gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);

      wxString fieldText;

      float value = mPlugin->getParameter(mParameters[p].identifier);

      toggles[p] = 0;
      combos[p] = 0;
      sliders[p] = 0;
      fields[p] = 0;

      if (mParameters[p].isQuantized &&
          mParameters[p].quantizeStep == 1.0 &&
          mParameters[p].minValue == 0.0 &&
          mParameters[p].maxValue == 1.0) {

         toggles[p] = new wxCheckBox(w, p, wxT(""));
         toggles[p]->SetValue(value > 0.5);
         gridSizer->Add(toggles[p], 0, wxALL, 5);
         ConnectFocus(toggles[p]);

         gridSizer->Add(1, 1, 0);
         gridSizer->Add(1, 1, 0);
         gridSizer->Add(1, 1, 0);

      } else if (mParameters[p].isQuantized &&
                 mParameters[p].quantizeStep == 1.0 &&
                 !mParameters[p].valueNames.empty()) {

         wxArrayString choices;
         wxString selected;

         for (size_t i = 0; i < mParameters[p].valueNames.size(); ++i) {
            wxString choice = wxString
               (mParameters[p].valueNames[i].c_str(), wxConvISO8859_1);
            if (int(value - mParameters[p].minValue + 0.5) == i) {
               selected = choice;
            }
            choices.Add(choice);
         }

         combos[p] = new wxComboBox(w, p, selected,
                                    wxDefaultPosition, wxDefaultSize,
                                    choices, wxCB_READONLY);

         gridSizer->Add(1, 1, 0);
         gridSizer->Add(1, 1, 0);

         gridSizer->Add(combos[p], 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | 
wxALL, 5);
         ConnectFocus(combos[p]);

         gridSizer->Add(1, 1, 0);

      } else {

         fieldText = Internat::ToDisplayString(value);

         fields[p] = new wxTextCtrl(w, p, fieldText);
         gridSizer->Add(fields[p], 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
         ConnectFocus(fields[p]);

         wxString str = Internat::ToDisplayString(mParameters[p].minValue);
         item = new wxStaticText(w, 0, str);
         gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | 
wxALL, 5);

         sliders[p] =
             new wxSlider(w, p,
                          0, 0, 1000,
                          wxDefaultPosition,
                          wxSize(100, -1));
         gridSizer->Add(sliders[p], 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | 
wxALL, 5);
         ConnectFocus(sliders[p]);

         str = Internat::ToDisplayString(mParameters[p].maxValue);
         item = new wxStaticText(w, 0, str);
         gridSizer->Add(item, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | 
wxALL, 5);
      }
   }

   // Set all of the sliders based on the value in the
   // text fields
   inSlider = false; // Now we're ready for HandleText to actually do something.
   HandleText();
   
   paramSizer->Add(gridSizer, 1, wxEXPAND | wxALL, 5);
   w->SetSizer(paramSizer);

   Layout();
   Fit();
   SetSizeHints(GetSize());
}

VampEffectDialog::~VampEffectDialog()
{
   delete[] sliders;
   delete[] fields;
   delete[] labels;
   delete[] toggles;
   delete[] combos;
}

void VampEffectDialog::OnCheckBox(wxCommandEvent &event)
{
   int p = event.GetId();

   mPlugin->setParameter(mParameters[p].identifier, toggles[p]->GetValue());
}

void VampEffectDialog::OnComboBox(wxCommandEvent &event)
{
   int p = event.GetId();

   if (p == 9999) {
      // special value for programs
      Vamp::Plugin::ProgramList programs = mPlugin->getPrograms();
      for (size_t i = 0; i < programs.size(); ++i) {
         if (wxString(programs[i].c_str(), wxConvISO8859_1) ==
             programCombo->GetValue()) {
            mPlugin->selectProgram(programs[i]);
            break;
         }
      }
      UpdateFromPlugin();
      return;
   }

   int value = -1;
   for (size_t i = 0; i < mParameters[p].valueNames.size(); ++i) {
      if (wxString(mParameters[p].valueNames[i].c_str(), wxConvISO8859_1) ==
          combos[p]->GetValue()) {
         value = i;
         break;
      }
   }
   if (value >= 0) {
      mPlugin->setParameter(mParameters[p].identifier, value);
   }
}

void VampEffectDialog::OnSlider(wxCommandEvent &event)
{
   int p = event.GetId();

   // if we don't add the following three lines, changing
   // the value of the slider will change the text, which
   // will change the slider, and so on.  This gets rid of
   // the implicit loop.
   if (inText) return;
   inSlider = true;

   float val;
   float lower = mParameters[p].minValue;
   float upper = mParameters[p].maxValue;
   float range;

   range = upper - lower;

   val = (sliders[p]->GetValue() / 1000.0) * range;

   if (mParameters[p].isQuantized) {

      float qs = mParameters[p].quantizeStep;

      if (qs != 0.0) {
         val = int(val / qs + 0.5) * qs;
      }
   }

   val += lower;

   wxString str = Internat::ToDisplayString(val);

   fields[p]->SetValue(str);

   mPlugin->setParameter(mParameters[p].identifier, val);

   inSlider = false;
}

void VampEffectDialog::OnTextCtrl(wxCommandEvent & WXUNUSED(event))
{
   HandleText();
}

void VampEffectDialog::HandleText()
{
   // if we don't add the following three lines, changing
   // the value of the slider will change the text, which
   // will change the slider, and so on.  This gets rid of
   // the implicit loop.

   if (inSlider) return;
   inText = true;

   for (unsigned long p = 0; p < mParameters.size(); p++) {

      if (mParameters[p].isQuantized &&
          mParameters[p].quantizeStep == 1.0) {

         if (mParameters[p].minValue == 0.0 &&
             mParameters[p].maxValue == 1.0) {
            // toggle, not slider
            continue;
         }

         if (!mParameters[p].valueNames.empty()) {
            // combo, not slider
            continue;
         }
      }

      double dval;
      float val;
      float lower = mParameters[p].minValue;
      float upper = mParameters[p].maxValue;
      float range;

      dval = Internat::CompatibleToDouble(fields[p]->GetValue());
      val = dval;

      range = upper - lower;

      if (val < lower) val = lower;
      if (val > upper) val = upper;

      if (mParameters[p].isQuantized) {

         float qs = mParameters[p].quantizeStep;

         if (qs != 0.0) {
            val = int((val - lower) / qs + 0.5) * qs + lower;
         }
      }

      mPlugin->setParameter(mParameters[p].identifier, val);

      sliders[p]->SetValue((int)(((val-lower)/range) * 1000.0 + 0.5));      
   }

   inText = false;
}

void VampEffectDialog::UpdateFromPlugin()
{
   inSlider = true;

   for (unsigned long p = 0; p < mParameters.size(); p++) {

      float value = mPlugin->getParameter(mParameters[p].identifier);

      if (mParameters[p].isQuantized &&
          mParameters[p].quantizeStep == 1.0 &&
          mParameters[p].minValue == 0.0 &&
          mParameters[p].maxValue == 1.0) {

         toggles[p]->SetValue(value > 0.5);

      } else if (mParameters[p].isQuantized &&
                 mParameters[p].quantizeStep == 1.0 &&
                 !mParameters[p].valueNames.empty()) {

         wxString selected;

         for (size_t i = 0; i < mParameters[p].valueNames.size(); ++i) {
            wxString choice = wxString
               (mParameters[p].valueNames[i].c_str(), wxConvISO8859_1);
            if (int(value - mParameters[p].minValue + 0.5) == i) {
               selected = choice;
               break;
            }
         }

         combos[p]->SetValue(selected);

      } else {

         fields[p]->SetValue(Internat::ToDisplayString(value));
      }
   }

   inSlider = false;
   HandleText();
}

void VampEffectDialog::OnOK(wxCommandEvent & WXUNUSED(event))
{
   EndModal(TRUE);
}

void VampEffectDialog::OnCancel(wxCommandEvent & WXUNUSED(event))
{
   EndModal(FALSE);
}

void VampEffectDialog::ConnectFocus(wxControl *c)
{
   c->GetEventHandler()->Connect(wxEVT_SET_FOCUS,
                                 
wxFocusEventHandler(VampEffectDialog::ControlSetFocus));
}

void VampEffectDialog::DisconnectFocus(wxControl *c)
{
   c->GetEventHandler()->Disconnect(wxEVT_SET_FOCUS,
                                 
wxFocusEventHandler(VampEffectDialog::ControlSetFocus));
}

void VampEffectDialog::ControlSetFocus(wxFocusEvent &event)
{
   wxControl *c = (wxControl *) event.GetEventObject();
   wxScrolledWindow *p = (wxScrolledWindow *) c->GetParent();
   wxRect r = c->GetRect();
   wxRect rv = p->GetRect();
   rv.y = 0;

   event.Skip();

   int y;
   int yppu;
   p->GetScrollPixelsPerUnit(NULL, &yppu);

   if (r.y >= rv.y && r.GetBottom() <= rv.GetBottom()) {
      return;
   }

   if (r.y < rv.y) {
      p->CalcUnscrolledPosition(0, r.y, NULL, &r.y);
      y = r.y / yppu;
   }
   else {
      p->CalcUnscrolledPosition(0, r.y, NULL, &r.y);
      y = (r.GetBottom() - rv.GetBottom() + yppu) / yppu;
   }

   p->Scroll(-1, y);
};

// Indentation settings for Vim and Emacs and unique identifier for Arch, a
// version control system. Please do not modify past this point.
//
// Local Variables:
// c-basic-offset: 3
// indent-tabs-mode: nil
// End:
//
// vim: et sts=3 sw=3
// arch-tag: 7e4a0346-c3ec-45de-9f71-818c6e34a094

--- NEW FILE: VampEffect.h ---
/**********************************************************************

  Audacity: A Digital Audio Editor

  VampEffect.h

  Chris Cannam

  Vamp is an audio analysis and feature extraction plugin API.
  http://www.vamp-plugins.org/

**********************************************************************/

#include "../Effect.h"
#include "../../LabelTrack.h"

class wxSlider;
class wxStaticText;
class wxTextCtrl;
class wxCheckBox;
class wxComboBox;

#include <wx/dialog.h>

//#include <vamp-sdk/hostext/PluginLoader.h>
#include "../../../lib-src/libvamp/vamp-sdk/hostext/PluginLoader.h"

void LoadVampPlugins();

class VampEffect : public Effect {
   
 public:

   VampEffect(Vamp::HostExt::PluginLoader::PluginKey key,
              int output,
              bool hasParameters,
              wxString name);
   virtual ~VampEffect();

   virtual wxString GetEffectName();
   
   virtual wxString GetEffectIdentifier();

   virtual wxString GetEffectAction();

   virtual int GetEffectFlags();

   virtual bool Init();

   virtual bool PromptUser();

   virtual bool Process();

   virtual void End();

 private:

   VampEffect(const VampEffect &);
   VampEffect &operator=(const VampEffect &);

   Vamp::HostExt::PluginLoader::PluginKey mKey;
   int mOutput;
   bool mHasParameters;
   wxString mName;
   double mRate;

   Vamp::Plugin *mPlugin;

   void GetSamples(WaveTrack *track,
                   longSampleCount *start,
                   sampleCount *len);

   void AddFeatures(LabelTrack *track,
                    Vamp::Plugin::FeatureSet &features);
};


class VampEffectDialog : public wxDialog {

   DECLARE_DYNAMIC_CLASS(VampEffectDialog)

 public:
   VampEffectDialog(VampEffect *effect,
                    wxWindow *parent,
                    Vamp::Plugin *plugin);
   ~VampEffectDialog();

   void OnCheckBox(wxCommandEvent & event);
   void OnComboBox(wxCommandEvent & event);
   void OnSlider(wxCommandEvent & event);
   void OnTextCtrl(wxCommandEvent & event);
   void OnOK(wxCommandEvent & event);
   void OnCancel(wxCommandEvent & event);
   void OnPreview(wxCommandEvent & event);
   void ControlSetFocus(wxFocusEvent & event);

   DECLARE_EVENT_TABLE()

 private:
   void HandleText();
   void UpdateFromPlugin();
   void ConnectFocus(wxControl *c);
   void DisconnectFocus(wxControl *c);
   bool inSlider;
   bool inText;

   VampEffect *mEffect;
   Vamp::Plugin *mPlugin;
   Vamp::Plugin::ParameterList mParameters;

   wxSlider **sliders;
   wxTextCtrl **fields;
   wxStaticText **labels;
   wxCheckBox **toggles;
   wxComboBox **combos;
   wxComboBox *programCombo;
};

// Indentation settings for Vim and Emacs and unique identifier for Arch, a
// version control system. Please do not modify past this point.
//
// Local Variables:
// c-basic-offset: 3
// indent-tabs-mode: nil
// End:
//
// vim: et sts=3 sw=3
// arch-tag: d8622b59-5c08-4e7f-a170-2502ff8af8e5

--- NEW FILE: LoadVamp.cpp ---
/**********************************************************************

  Audacity: A Digital Audio Editor

  LoadVamp.cpp

  Chris Cannam

**********************************************************************/

//#include <vamp-sdk/hostext/PluginLoader.h>
#include "../../../lib-src/libvamp/vamp-sdk/hostext/PluginLoader.h"

#include "VampEffect.h"

#include <iostream>

using namespace Vamp;
using namespace Vamp::HostExt;

void LoadVampPlugins()
{
   PluginLoader *loader = PluginLoader::getInstance();

   PluginLoader::PluginKeyList keys = loader->listPlugins();

   for (PluginLoader::PluginKeyList::iterator i = keys.begin();
        i != keys.end(); ++i) {

      Plugin *vp = loader->loadPlugin(*i, 48000); // rate doesn't matter here
      if (!vp) continue;

      // For now we only support "time instants" conformable outputs

      Plugin::OutputList outputs = vp->getOutputDescriptors();

      int n = 0;

      bool hasParameters = !vp->getParameterDescriptors().empty();
      
      for (Plugin::OutputList::iterator j = outputs.begin();
           j != outputs.end(); ++j) {
         
         if (j->hasFixedBinCount &&
             j->binCount == 0 &&
             j->sampleType == Plugin::OutputDescriptor::VariableSampleRate) {

            wxString name = LAT1CTOWX(vp->getName().c_str());

            if (outputs.size() > 1) {
               // This is not the plugin's only output.
               // Use "plugin name: output name" as the effect name,
               // unless the output name is the same as the plugin name
               wxString outputName = LAT1CTOWX(j->name.c_str());
               if (outputName != name) {
                  name = wxString::Format(_("%s: %s"),
                                          name.c_str(), outputName.c_str());
               }
            }

            VampEffect *effect = new VampEffect(*i, n, hasParameters, name);
            Effect::RegisterEffect(effect);
         }

         ++n;
      }

      delete vp;
   }
}


// Indentation settings for Vim and Emacs and unique identifier for Arch, a
// version control system. Please do not modify past this point.
//
// Local Variables:
// c-basic-offset: 3
// indent-tabs-mode: nil
// End:
//
// vim: et sts=3 sw=3
// arch-tag: 21a6d3fe-1003-4cec-a44c-4a16335b5cda



-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Audacity-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/audacity-cvs

Reply via email to