Update of /cvsroot/audacity/audacity-src/src/effects/nyquist
In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv16552/src/effects/nyquist

Modified Files:
        Nyquist.cpp Nyquist.h 
Log Message:
Added support for Nyquist plugins written with the SAL syntax.
Added support to the EffectNyquist and the Nyquist bridge for better debug 
handling.
EffectNyquist now yields while the actually nyquist plugin is running (before 
the progress dialog kicks in) to allow window refreshes
Added a module interface to EffectNyquist in preparation for an upcoming module.
Added a couple more module dispatch points.

Index: Nyquist.h
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/effects/nyquist/Nyquist.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- Nyquist.h   25 Jan 2009 22:42:16 -0000      1.14
+++ Nyquist.h   5 Feb 2009 18:12:17 -0000       1.15
@@ -26,6 +26,8 @@
 
 #include "nyx.h"
 
+#include <string>
+
 class WaveTrack;
 
 class NyqControl {
@@ -43,9 +45,9 @@
    int ticks;
 };
 
-WX_DECLARE_OBJARRAY(NyqControl, NyqControlArray);
+WX_DECLARE_USER_EXPORTED_OBJARRAY(NyqControl,  NyqControlArray, 
AUDACITY_DLL_API);
 
-class EffectNyquist: public Effect {
+class AUDACITY_DLL_API EffectNyquist: public Effect {
 
 public:
    
@@ -58,6 +60,13 @@
       return mOK;
    }
 
+   void Continue();
+   void Break();
+   void Stop();
+
+   void SetCommand(wxString cmd);
+   wxString GetOutput();
+
    virtual wxString GetEffectName() {
       return mName;
    }
@@ -99,6 +108,8 @@
                    long start, long len, long totlen);
    int PutCallback(float *buffer, int channel,
                    long start, long len, long totlen);
+   void OutputCallback(int c);
+   void OSCallback();
 
    static int StaticGetCallback(float *buffer, int channel,
                                 long start, long len, long totlen,
@@ -106,6 +117,8 @@
    static int StaticPutCallback(float *buffer, int channel,
                                 long start, long len, long totlen,
                                 void *userdata);
+   static void StaticOutputCallback(int c, void *userdata);
+   static void StaticOSCallback(void *userdata);
 
    bool       ProcessOne();
 
@@ -119,6 +132,13 @@
    wxFileName       mFileName;
    wxDateTime       mFileModified;
 
+   bool mStop;
+   bool mBreak;
+   bool mCont;
+
+   bool             mCompiler;
+   bool             mIsSal;
+   bool             mExternal;
    bool             mInteractive;
    bool             mOK;
    wxString         mCmd;
@@ -126,7 +146,7 @@
    wxString         mAction;
    wxString         mInfo;
    bool             mDebug;
-   wxString         mDebugOutput;
+   std::string      mDebugOutput;
 
    NyqControlArray  mControls;
 
@@ -146,9 +166,9 @@
    sampleCount      mCurBufferLen[2];
 
    WaveTrack       *mOutputTrack[2];
-   
+
    std::set<wxString> mCategories;
-   
+
 };
 
 class NyquistDialog:public wxDialog {

Index: Nyquist.cpp
===================================================================
RCS file: /cvsroot/audacity/audacity-src/src/effects/nyquist/Nyquist.cpp,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -d -r1.68 -r1.69
--- Nyquist.cpp 25 Jan 2009 22:42:16 -0000      1.68
+++ Nyquist.cpp 5 Feb 2009 18:12:17 -0000       1.69
@@ -61,6 +61,9 @@
 #endif
 
 #include <locale.h>
+#include <iostream>
+#include <ostream>
+#include <sstream>
 
 #include <wx/arrimpl.cpp>
 WX_DEFINE_OBJARRAY(NyqControlArray);
@@ -89,6 +92,20 @@
 }
 #endif
 
+void EffectNyquist::Break()
+{
+   mBreak = true;
+}
+
+void EffectNyquist::Continue()
+{
+   mCont = true;
+}
+
+void EffectNyquist::Stop()
+{
+   mStop = true;
+}
 
 #define UNINITIALIZED_CONTROL ((double)99999999.99)
 
@@ -163,6 +180,34 @@
       return;
    }
 
+   if (len == 2 && tokens[0] == wxT("codetype")) {
+      if (tokens[1] == wxT("lisp")) {
+         mIsSal = false;
+      }
+      else if (tokens[1] == wxT("sal")) {
+         mIsSal = true;
+      }
+      return;
+   }
+
+   if (len >= 2 && tokens[0] == wxT("debugflags")) {
+      for (int i = 1; i < len; i++) {
+         if (tokens[i] == wxT("trace")) {
+            mDebug = true;
+         }
+         else if (tokens[i] == wxT("notrace")) {
+            mDebug = false;
+         }
+         else if (tokens[i] == wxT("compiler")) {
+            mCompiler = true;
+         }
+         else if (tokens[i] == wxT("nocompiler")) {
+            mCompiler = false;
+         }
+      }
+      return;
+   }
+
    // We support versions 1, 2 and 3
    // (Version 2 added support for string parameters.)
    // (Version 3 added support for choice parameters.)
@@ -237,6 +282,7 @@
    mCmd = wxT("");
    mFlags = PROCESS_EFFECT | PLUGIN_EFFECT;
    mOK = false;
+   mIsSal = false;
    mControls.Clear();
 
    int i;
@@ -253,14 +299,24 @@
 
 EffectNyquist::EffectNyquist(wxString fName)
 {
-   mInteractive = false;
    mAction = _("Applying Nyquist Effect...");
+   mCmd = wxEmptyString;
+   mFlags = HIDDEN_EFFECT;
+   mInteractive = false;
+   mExternal = false;
+   mCompiler = false;
+   mDebug = false;
+   mIsSal = false;
+   mOK = false;
+
+   mStop = false;
+   mBreak = false;
+   mCont = false;
 
    if (fName == wxT("")) {
       // Interactive Nyquist
       mOK = true;
       mInteractive = true;
-      mCmd = wxT("");
       mName = _("Nyquist Prompt...");
       mFlags = PROCESS_EFFECT | BUILTIN_EFFECT | ADVANCED_EFFECT;
       return;
@@ -316,13 +372,34 @@
    return ::wxFileExists(fname);
 }
 
+void EffectNyquist::SetCommand(wxString cmd)
+{
+   mExternal = true;
+   mInteractive = false;
+   mCmd = wxT("");
+   mFlags = HIDDEN_EFFECT;
+   mOK = false;
+   mIsSal = false;
+   mControls.Clear();
+
+   wxStringTokenizer lines(cmd, wxT("\n"));
+   while (lines.HasMoreTokens()) {
+      wxString line = lines.GetNextToken();
+      
+      if (line.Length() > 1 && line.GetChar(0) == wxT(';'))
+         Parse(line);
+      else
+         mCmd += line + wxT("\n");
+   }
+}
+
 bool EffectNyquist::PromptUser()
 {
    if (!SetXlispPath())
       return false;
 
    if (mInteractive) {
-      NyquistInputDialog dlog(mParent, -1,
+      NyquistInputDialog dlog(wxGetTopLevelParent(NULL), -1,
                               _NoAcc("Nyquist Prompt..."),
                               _("Enter Nyquist Command: "),
                               mCmd);
@@ -334,21 +411,20 @@
 
       if (result == eDebugID)
          mDebug = true;
-      else
-         mDebug = false;
-      
+
       mCmd = dlog.GetCommand();
 
       return true;
    }
 
-   if (mFileName.GetModificationTime().IsLaterThan(mFileModified)) {
-      ParseFile();
-      mFileModified = mFileName.GetModificationTime();
+   if (!mExternal) {
+      if (mFileName.GetModificationTime().IsLaterThan(mFileModified)) {
+         ParseFile();
+         mFileModified = mFileName.GetModificationTime();
+      }
    }
 
    if (mControls.GetCount() == 0) {
-      mDebug = false;
       return true;
    }
 
@@ -389,8 +465,6 @@
    
    if (result == eDebugID)
       mDebug = true;
-   else
-      mDebug = false;
 
    return true;
 }
@@ -398,7 +472,11 @@
 bool EffectNyquist::Process()
 {
    bool success = true;
-   
+
+   if (mExternal) {
+      mProgress->Hide();
+   }
+
    this->CopyInputWaveTracks(); // Set up mOutputWaveTracks.
    TrackListIterator iter(mOutputWaveTracks);
    mCurTrack[0] = (WaveTrack *) iter.First();
@@ -409,7 +487,12 @@
    mProgressTot = 0;
    mScale = (mFlags & PROCESS_EFFECT ? 0.5 : 1.0) / GetNumWaveGroups();
 
-   mDebugOutput = wxT("");
+   mStop = false;
+   mBreak = false;
+   mCont = false;
+
+   mDebugOutput = "";
+
    while (mCurTrack[0]) {
       mCurNumChannels = 1;
       if (mT1 >= mT0) {
@@ -447,16 +530,19 @@
 
  finish:
 
-   if (mDebug) {
+   if (mDebug && !mExternal) {
       NyquistOutputDialog dlog(mParent, -1,
                                _("Nyquist"),
                                _("Nyquist Output: "),
-                               mDebugOutput);
+                               wxString(mDebugOutput.c_str(), 
wxConvISO8859_1));
       dlog.CentreOnParent();
       dlog.ShowModal();
    }
 
-   this->ReplaceProcessedWaveTracks(success); 
+   this->ReplaceProcessedWaveTracks(success);
+
+   mDebug = false;
+
    return success;
 }
 
@@ -523,6 +609,34 @@
       return -1; // failure
 }
 
+void EffectNyquist::OutputCallback(int c)
+{
+   if (mDebug && !mExternal) {
+      mDebugOutput += (char)c;
+      return;
+   }
+
+   std::cout << (char)c;
+}
+
+void EffectNyquist::OSCallback()
+{
+   if (mStop) {
+      mStop = false;
+      nyx_stop();
+   }
+   else if (mBreak) {
+      mBreak = false;
+      nyx_break();
+   }
+   else if (mCont) {
+      mCont = false;
+      nyx_continue();
+   }
+
+   wxYieldIfNeeded();
+}
+
 int EffectNyquist::StaticGetCallback(float *buffer, int channel,
                                      long start, long len, long totlen,
                                      void *userdata)
@@ -539,6 +653,16 @@
    return This->PutCallback(buffer, channel, start, len, totlen);
 }
 
+void EffectNyquist::StaticOutputCallback(int c, void *This)
+{
+   ((EffectNyquist *)This)->OutputCallback(c);
+}
+
+void EffectNyquist::StaticOSCallback(void *This)
+{
+   ((EffectNyquist *)This)->OSCallback();
+}
+
 bool EffectNyquist::ProcessOne()
 {
    // libnyquist breaks except in LC_NUMERIC=="C".
@@ -548,11 +672,43 @@
    setlocale(LC_NUMERIC, "C");
 
    nyx_rval rval;
+   wxString code = mCmd;
 
-   nyx_init();
+#if defined(SAL_SEPARATE_COMPILE)
+   if (mIsSal) {
+      code.Replace(wxT("\""), wxT("\\\""));
 
-   if (mDebug)
-      nyx_capture_output(65536);
+      wxString c;
+      c =  wxT("(setf *tracenable* T)\n");
+      c += wxT("(setf *sal-call-stack* nil)\n");
+      c += wxT("(setf *sal-compiler-debug* t)\n");
+      c += wxT("(format nil \"~s\" (sal-compile \"define variable 
*audacity-plugin-result*\n") +
+           code +
+           wxT("\nset *audacity-plugin-result* = main()\n\" nil t nil))\n");
+
+      nyx_init();
+      nyx_set_os_callback(StaticOSCallback, (void *)this);
+      nyx_capture_output(StaticOutputCallback, (void *)this);
+      rval = nyx_eval_expression(c.mb_str());
+
+      if (rval == nyx_string) {
+         code = wxString(nyx_get_string(), wxConvISO8859_1);
+      }
+
+       nyx_cleanup();
+       setlocale(LC_NUMERIC, "");
+
+       if (rval != nyx_string) {
+         wxMessageBox(_("SAL compile didn't return anything"), wxT("Nyquist"),
+                      wxOK | wxCENTRE, mParent);
+         return true;
+      }
+   }
+#endif
+
+   nyx_init();
+   nyx_set_os_callback(StaticOSCallback, (void *)this);
+   nyx_capture_output(StaticOutputCallback, (void *)this);
 
    if( !( mFlags & INSERT_EFFECT ) )
       nyx_set_input_audio(StaticGetCallback, (void *)this,
@@ -565,6 +721,9 @@
 
    if (mDebug) {
       cmd = cmd + wxT("(setf *tracenable* T)\n");
+      if (mExternal) {
+         cmd = cmd + wxT("(setf *breakenable* T)\n");
+      }
    }
 
    for(unsigned int j=0; j<mControls.GetCount(); j++) {
@@ -585,23 +744,45 @@
                                     str.c_str());
       }
    }
-   
-   cmd += mCmd;
-   
-   //wxMessageBox(cmd);
-   
+
+#if !defined(SAL_SEPARATE_COMPILE)
+   if (mIsSal) {
+      wxString str = mCmd;
+      str.Replace(wxT("\""), wxT("\\\""));
+
+      if (mCompiler) {
+         cmd += wxT("(setf *sal-compiler-debug* t)\n");
+      }
+
+      cmd += wxT("(setf *sal-call-stack* nil)\n");
+      cmd += wxT("(setf *audacity-plugin-result* nil)\n");
+      cmd += wxT("(eval (sal-compile \"define variable 
*audacity-plugin-result*\n") +
+             str +
+             wxT("\nset *audacity-plugin-result* = main()\n\" nil t nil))\n");
+      cmd += wxT("(eval *audacity-plugin-result*)");
+   }
+   else {
+      cmd += mCmd;
+   }
+#endif
+
+#if defined(SAL_SEPARATE_COMPILE)
+   if (mIsSal) {
+      cmd += wxT("(setf *audacity-plugin-result* nil)\n");
+   }
+
+   cmd += code;
+
+   if (mIsSal) {
+      cmd += wxT("(eval *audacity-plugin-result*)");
+   }
+#endif
+
    int i;
        for (i = 0; i < mCurNumChannels; i++)
                mCurBuffer[i] = NULL;
-   rval = nyx_eval_expression(cmd.mb_str());
 
-   if (mDebug) {
-      int len;
-      const char *str;
-
-      nyx_get_captured_output(&len, &str);
-      mDebugOutput += wxString(str, wxConvISO8859_1, len);
-   }
+   rval = nyx_eval_expression(cmd.mb_str());
 
    if (rval == nyx_string) {
       wxMessageBox(wxString(nyx_get_string(), wxConvISO8859_1), wxT("Nyquist"),
@@ -634,8 +815,8 @@
    }
 
    if (rval == nyx_labels) {
-      int numLabels = nyx_get_num_labels();
-      int l;
+      unsigned int numLabels = nyx_get_num_labels();
+      unsigned int l;
       LabelTrack *ltrack = NULL;
 
       TrackListIterator iter(mTracks);
@@ -733,6 +914,10 @@
       mOutputTrack[i] = NULL;
    }
 
+   nyx_capture_output(StaticOutputCallback, (void *)NULL);
+
+   nyx_set_os_callback(StaticOSCallback, (void *)NULL);
+
    nyx_cleanup();
 
    // Reset locale


------------------------------------------------------------------------------
Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM)
software. With Adobe AIR, Ajax developers can use existing skills and code to
build responsive, highly engaging applications that combine the power of local
resources and data with the reach of the web. Download the Adobe AIR SDK and
Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com
_______________________________________________
Audacity-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/audacity-cvs

Reply via email to