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

📄 nyquist.cpp

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************  Audacity: A Digital Audio Editor  Nyquist.cpp  Dominic Mazzoni**********************************************************************/#include <math.h>#include <locale.h>#include <wx/defs.h>#include <wx/log.h>#include <wx/intl.h>#include <wx/msgdlg.h>#include <wx/textdlg.h>#include <wx/textfile.h>#include "../../Audacity.h"#include "../../AudacityApp.h"#include "../../LabelTrack.h"#include "../../Internat.h"#include "Nyquist.h"#include <locale.h>#include <wx/arrimpl.cpp>WX_DEFINE_OBJARRAY(NyqControlArray);wxString EffectNyquist::mXlispPath;#define NYQ_CTRL_INT 0#define NYQ_CTRL_REAL 1#define NYQ_CTRL_STRING 2extern "C" {   extern void set_xlisp_path(const char *p);}#if defined(USE_NYQUIST) && defined(__WXMSW__) && !defined(__CYGWIN__)// Nyquist needs a random function and non-Cygwin MSW doesn't provide one...extern "C" {   long random_seed = 1534781L;   short random(short lo, short hi)   {      random_seed *= 13L;      random_seed += 1874351L;      return((short)(lo + (((hi + 1 - lo) * ((0x00ffff00 & random_seed) >> 8)) >> 16)));   }}#endif#define UNINITIALIZED_CONTROL ((double)99999999.99)wxString EffectNyquist::UnQuote(wxString s){   wxString out;   int len = s.Length();      if (len>=2 && s.GetChar(0)==wxT('\"') && s.GetChar(len-1)==wxT('\"'))      return s.Mid(1, len-2);   else      return s;}double EffectNyquist::GetCtrlValue(wxString s){   if (s == wxT("rate")) {      TrackListIterator iter(mWaveTracks);      return ((WaveTrack *)iter.First())->GetRate();   }   else {      double d;      s.ToDouble(&d);      return d;   }}void EffectNyquist::Parse(wxString line){   wxArrayString tokens;   int i;   int len = line.Length();   bool sl = false;   bool q = false;   wxString tok = wxT("");   for(i=1; i<len; i++) {      if (line.GetChar(i)==wxT('\\'))         sl = true;      else if (line.GetChar(i)==wxT('"'))         q = !q;      else {         if (!q && !sl && line.GetChar(i)==wxT(' ') || line.GetChar(i)==wxT('\t')) {            tokens.Add(tok);            tok = wxT("");         }         else if (sl && line.GetChar(i)==wxT('n'))            tok += wxT('\n');         else            tok += line.GetChar(i);                  sl = false;      }   }   if (tok != wxT(""))      tokens.Add(tok);   len = tokens.GetCount();   if (len < 1)      return;   if (len==2 && tokens[0]==wxT("nyquist") && tokens[1]==wxT("plug-in")) {      mOK = true;      return;   }   if (len>=2 && tokens[0]==wxT("type")) {      if (tokens[1]==wxT("process"))         mFlags = PROCESS_EFFECT | PLUGIN_EFFECT;      if (tokens[1]==wxT("generate"))         mFlags = INSERT_EFFECT | PLUGIN_EFFECT;      if (tokens[1]==wxT("analyze"))         mFlags = ANALYZE_EFFECT | PLUGIN_EFFECT;      return;   }   // We support versions 1 and 2   // (Version 2 added support for string parameters.)   if (len>=2 && tokens[0]==wxT("version")) {      if (tokens[1]==wxT("1") || tokens[1]==wxT("2")) {         // We're okay      }      else {         // This is an unsupported plug-in version         mOK = false;         return;      }   }   if (len>=2 && tokens[0]==wxT("name")) {      mName = UnQuote(tokens[1]);      return;   }   if (len>=2 && tokens[0]==wxT("action")) {      mAction = UnQuote(tokens[1]);      return;   }   if (len>=2 && tokens[0]==wxT("info")) {      mInfo = UnQuote(tokens[1]);      return;   }   if (len>=6 && tokens[0]==wxT("control")) {      NyqControl ctrl;        ctrl.var = tokens[1];      ctrl.name = tokens[2];      ctrl.label = tokens[4];      ctrl.valStr = tokens[5];       if (tokens[3]==wxT("string"))         ctrl.type = NYQ_CTRL_STRING;      else {         if (len < 8)            return;                   if (tokens[3]==wxT("real"))            ctrl.type = NYQ_CTRL_REAL;         else            ctrl.type = NYQ_CTRL_INT;                   ctrl.lowStr = tokens[6];         ctrl.highStr = tokens[7];      }      ctrl.val = UNINITIALIZED_CONTROL;      mControls.Add(ctrl);   }}void EffectNyquist::ParseFile(){   wxTextFile f(FILENAME(mFileName.GetFullPath()));   if (!f.Open())      return;   mCmd = wxT("");   mFlags = PROCESS_EFFECT | PLUGIN_EFFECT;   mOK = false;   mControls.Clear();   int i;   int len = f.GetLineCount();   wxString line;   for(i=0; i<len; i++) {      line = f[i];      if (line.Length()>1 && line.GetChar(0)==wxT(';'))         Parse(line);      else         mCmd += line + wxT("\n");   }}EffectNyquist::EffectNyquist(wxString fName){   mInteractive = false;   mAction = _("Applying Nyquist Effect...");   if (fName == wxT("")) {      // Interactive Nyquist      mOK = true;      mInteractive = true;      mCmd = wxT("");      mName = _("Nyquist Prompt...");      mFlags = PROCESS_EFFECT | BUILTIN_EFFECT | ADVANCED_EFFECT;      return;   }   wxLogNull dontLog;   mName = wxFileName(fName).GetName();   mFileName = wxFileName(FILENAME(fName));   mFileModified = mFileName.GetModificationTime();   ParseFile();}EffectNyquist::~EffectNyquist(){}bool EffectNyquist::SetXlispPath(){   wxString fname;   fname = mXlispPath + wxFILE_SEP_PATH + wxT("nyinit.lsp");   if (!(::wxFileExists(FILENAME(fname))))      mXlispPath = wxT("");   if (mXlispPath == wxT("")) {      wxArrayString audacityPathList = wxGetApp().audacityPathList;      wxArrayString pathList;      wxArrayString files;      unsigned int i;      for(i=0; i<audacityPathList.GetCount(); i++) {         wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;         wxGetApp().AddUniquePathToPathList(prefix + wxT("nyquist"),                                            pathList);      }      wxGetApp().FindFilesInPathList(wxT("nyquist.lsp"), pathList, wxFILE, files);      if (files.GetCount() > 0) {         mXlispPath = ::wxPathOnly(files[0]);      }   }   #ifdef _UNICODE      /* set_xlisp_path doesn't handle fn_Str() in Unicode build. May or may not actually work. */      set_xlisp_path(mXlispPath.mb_str());   #else // ANSI      set_xlisp_path(mXlispPath.fn_str());   #endif // Unicode/ANSI   fname = mXlispPath + wxFILE_SEP_PATH + wxT("nyinit.lsp");   return ::wxFileExists(FILENAME(fname));}bool EffectNyquist::PromptUser(){   if (!SetXlispPath())      return false;   if (mInteractive) {      NyquistInputDialog dlog(mParent, -1,                              _("Nyquist Prompt"),                              _("Enter Nyquist Command: "),                              mCmd);      dlog.CentreOnParent();      int result = dlog.ShowModal();      if (result == wxID_CANCEL)         return false;      if (result == wxID_MORE)         mDebug = true;      else         mDebug = false;            mCmd = dlog.GetCommand();      return true;   }   if (mFileName.GetModificationTime().IsLaterThan(mFileModified)) {      ParseFile();      mFileModified = mFileName.GetModificationTime();   }   if (mControls.GetCount() == 0) {      mDebug = false;      return true;   }   for(unsigned int i=0; i<mControls.GetCount(); i++) {      NyqControl *ctrl = &mControls[i];      if (ctrl->type == NYQ_CTRL_STRING)         continue;      if (ctrl->val == UNINITIALIZED_CONTROL)         ctrl->val = GetCtrlValue(ctrl->valStr);      ctrl->low = GetCtrlValue(ctrl->lowStr);      ctrl->high = GetCtrlValue(ctrl->highStr);      if (ctrl->high < ctrl->low)         ctrl->high = ctrl->low + 1;      if (ctrl->val < ctrl->low)         ctrl->val = ctrl->low;      if (ctrl->val > ctrl->high)         ctrl->val = ctrl->high;      ctrl->ticks = 1000;      if (ctrl->type==NYQ_CTRL_INT &&          (ctrl->high - ctrl->low < ctrl->ticks))         ctrl->ticks = (int)(ctrl->high - ctrl->low);   }   NyquistDialog dlog(mParent, -1, mName, mInfo, &mControls);   dlog.CentreOnParent();   int result = dlog.ShowModal();   if (result == wxID_CANCEL)      return false;      if (result == wxID_MORE)      mDebug = true;   else      mDebug = false;   return true;}bool EffectNyquist::Process(){   bool success = true;      TrackListIterator iter(mWaveTracks);   mCurTrack[0] = (WaveTrack *) iter.First();   mOutputTime = mT1 - mT0;   mCount = 0;   mProgress = 0;   mDebugOutput = wxT("");   while (mCurTrack[0]) {      mCurNumChannels = 1;      double trackStart = mCurTrack[0]->GetStartTime();      double trackEnd = mCurTrack[0]->GetEndTime();      double t0 = mT0 < trackStart? trackStart: mT0;      double t1 = mT1 > trackEnd? trackEnd: mT1;      if (t1 >= t0) {         if (mCurTrack[0]->GetLinked()) {            mCurNumChannels = 2;            mCurTrack[1] = (WaveTrack *)iter.Next();            if (mCurTrack[1]->GetRate() != mCurTrack[0]->GetRate()) {               wxMessageBox(_("Sorry, cannot apply effect on stereo tracks where the tracks don't match."),                             wxT("Nyquist"),                            wxOK | wxCENTRE, mParent);               return false;            }            mCurStart[1] = mCurTrack[1]->TimeToLongSamples(t0);         }         mCurStart[0] = mCurTrack[0]->TimeToLongSamples(t0);         longSampleCount end = mCurTrack[0]->TimeToLongSamples(t1);         mCurLen = (sampleCount)(end - mCurStart[0]);         success = ProcessOne();         if (!success)            goto finish;      }      mCurTrack[0] = (WaveTrack *) iter.Next();      mCount += mCurNumChannels;   }   mT1 = mT0 + mOutputTime; finish:   if (mDebug) {      NyquistOutputDialog dlog(mParent, -1,                               _("Nyquist"),                               _("Nyquist Output: "),                               mDebugOutput);      dlog.CentreOnParent();      dlog.ShowModal();   }   return success;}int EffectNyquist::GetCallback(float *buffer, int ch,                               long start, long len){   if (mCurBuffer[ch]) {      if ((mCurStart[ch] + start) < mCurBufferStart[ch] ||          (mCurStart[ch] + start)+len >          mCurBufferStart[ch]+mCurBufferLen[ch]) {         delete[] mCurBuffer[ch];         mCurBuffer[ch] = NULL;      }   }   if (!mCurBuffer[ch]) {      mCurBufferStart[ch] = (mCurStart[ch] + start);      mCurBufferLen[ch] = mCurTrack[ch]->GetBestBlockSize(mCurBufferStart[ch]);      if (mCurBufferLen[ch] < len)         mCurBufferLen[ch] = mCurTrack[ch]->GetIdealBlockSize();      if (mCurBufferStart[ch] + mCurBufferLen[ch] > mCurStart[ch] + mCurLen)         mCurBufferLen[ch] = mCurStart[ch] + mCurLen - mCurBufferStart[ch];      mCurBuffer[ch] = NewSamples(mCurBufferLen[ch], floatSample);      if (!mCurTrack[ch]->Get(mCurBuffer[ch], floatSample,                              mCurBufferStart[ch], mCurBufferLen[ch])) {         wxPrintf(wxT("GET error\n"));         return -1;      }   }   long offset = (mCurStart[ch] + start) - mCurBufferStart[ch];   CopySamples(mCurBuffer[ch] + offset*SAMPLE_SIZE(floatSample), floatSample,               (samplePtr)buffer, floatSample,               len);   if (ch==0) {      double progress = 1.0*(start+len)/mCurLen;      if (progress > mProgress)         mProgress = progress;      if (TotalProgress(mProgress))         return -1;   }   return 0;}int EffectNyquist::PutCallback(float *buffer, int channel,                               long start, long len){      if (mOutputTrack[channel]->Append((samplePtr)buffer, floatSample, len))      return 0;  // success   else      return -1; // failure}int EffectNyquist::StaticGetCallback(float *buffer, int channel,                                     long start, long len,                                     void *userdata){   EffectNyquist *This = (EffectNyquist *)userdata;   return This->GetCallback(buffer, channel, start, len);}int EffectNyquist::StaticPutCallback(float *buffer, int channel,                                     long start, long len,                                     void *userdata){   EffectNyquist *This = (EffectNyquist *)userdata;   return This->PutCallback(buffer, channel, start, len);}bool EffectNyquist::ProcessOne(){   // libnyquist breaks except in LC_NUMERIC=="C".   //   // MB: setlocale is not thread-safe.  Should use uselocale()   //     if available, or fix libnyquist to be locale-independent.   setlocale(LC_NUMERIC, "C");   nyx_rval rval;   nyx_init();   if (mDebug)

⌨️ 快捷键说明

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