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