void LabelDialog::OnExport(wxCommandEvent &event) { int cnt = mData.GetCount(); // Silly user (could just disable the button, but that's a hassle ;-)) if (cnt == 0) { wxMessageBox(_("No labels to export.")); return; } wxString fName; fName = FileSelector(_("Export Labels As:"), NULL, _("labels.txt"), wxT("txt"), wxT("*.txt"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER, this); if (fName == wxT("")) return; // Move existing files out of the way. Otherwise wxTextFile will // append to (rather than replace) the current file. if (wxFileExists(fName)) { #ifdef __WXGTK__ wxString safetyFileName = fName + wxT("~"); #else wxString safetyFileName = fName + wxT(".bak"); #endif if (wxFileExists(safetyFileName)) wxRemoveFile(safetyFileName); wxRename(fName, safetyFileName); } wxTextFile f(fName); #ifdef __WXMAC__ wxFile *temp = new wxFile(); temp->Create(fName); delete temp; #else f.Create(); #endif f.Open(); if (!f.IsOpened()) { wxMessageBox(_("Couldn't write to file: ") + fName); return; } // Transfer our collection to a temporary label track LabelTrack *lt = new LabelTrack(mDirManager); int i; for (i = 0; i < cnt; i++) { RowData *rd = mData[i]; lt->AddLabel(rd->stime, rd->etime, rd->title); } // Export them and clean lt->Export(f); delete lt; #ifdef __WXMAC__ f.Write(wxTextFileType_Mac); #else f.Write(); #endif f.Close(); }
bool EffectNyquist::ProcessOne() { nyx_rval rval; if (GetEffectFlags() & INSERT_EFFECT) { nyx_set_audio_params(mCurTrack[0]->GetRate(), 0); } else { nyx_set_audio_params(mCurTrack[0]->GetRate(), mCurLen); nyx_set_input_audio(StaticGetCallback, (void *)this, mCurNumChannels, mCurLen, mCurTrack[0]->GetRate()); } wxString cmd; if (mDebug) { cmd += wxT("(setf *tracenable* T)\n"); if (mExternal) { cmd += wxT("(setf *breakenable* T)\n"); } } for (unsigned int j = 0; j < mControls.GetCount(); j++) { if (mControls[j].type == NYQ_CTRL_REAL) { // We use Internat::ToString() rather than "%f" here because we // always have to use the dot as decimal separator when giving // numbers to Nyquist, whereas using "%f" will use the user's // decimal separator which may be a comma in some countries. cmd += wxString::Format(wxT("(setf %s %s)\n"), mControls[j].var.c_str(), Internat::ToString(mControls[j].val).c_str()); } else if (mControls[j].type == NYQ_CTRL_INT || mControls[j].type == NYQ_CTRL_CHOICE) { cmd += wxString::Format(wxT("(setf %s %d)\n"), mControls[j].var.c_str(), (int)(mControls[j].val)); } else if (mControls[j].type == NYQ_CTRL_STRING) { wxString str = mControls[j].valStr; str.Replace(wxT("\\"), wxT("\\\\")); str.Replace(wxT("\""), wxT("\\\"")); cmd += wxT("(setf "); // restrict variable names to 7-bit ASCII: cmd += mControls[j].var.c_str(); cmd += wxT(" \""); cmd += str; // unrestricted value will become quoted UTF-8 cmd += wxT("\")\n"); } } if (mIsSal) { wxString str = mCmd; str.Replace(wxT("\\"), wxT("\\\\")); str.Replace(wxT("\""), wxT("\\\"")); // this is tricky: we need SAL to call main so that we can get a // SAL traceback in the event of an error (sal-compile catches the // error and calls sal-error-output), but SAL does not return values. // We will catch the value in a special global aud:result and if no // error occurs, we will grab the value with a LISP expression str += wxT("\nset aud:result = main()\n"); if (mDebug) { // since we're about to evaluate SAL, remove LISP trace enable and // break enable (which stops SAL processing) and turn on SAL stack // trace cmd += wxT("(setf *tracenable* nil)\n"); cmd += wxT("(setf *breakenable* nil)\n"); cmd += wxT("(setf *sal-traceback* t)\n"); } if (mCompiler) { cmd += wxT("(setf *sal-compiler-debug* t)\n"); } cmd += wxT("(setf *sal-call-stack* nil)\n"); // if we do not set this here and an error occurs in main, another // error will be raised when we try to return the value of aud:result // which is unbound cmd += wxT("(setf aud:result nil)\n"); cmd += wxT("(sal-compile-audacity \"") + str + wxT("\" t t nil)\n"); // Capture the value returned by main (saved in aud:result), but // set aud:result to nil so sound results can be evaluated without // retaining audio in memory cmd += wxT("(prog1 aud:result (setf aud:result nil))\n"); } else { cmd += mCmd; } int i; for (i = 0; i < mCurNumChannels; i++) { mCurBuffer[i] = NULL; } rval = nyx_eval_expression(cmd.mb_str(wxConvUTF8)); if (rval == nyx_string) { wxMessageBox(NyquistToWxString(nyx_get_string()), wxT("Nyquist"), wxOK | wxCENTRE, mParent); return true; } if (rval == nyx_double) { wxString str; str.Printf(_("Nyquist returned the value:") + wxString(wxT(" %f")), nyx_get_double()); wxMessageBox(str, wxT("Nyquist"), wxOK | wxCENTRE, mParent); return true; } if (rval == nyx_int) { wxString str; str.Printf(_("Nyquist returned the value:") + wxString(wxT(" %d")), nyx_get_int()); wxMessageBox(str, wxT("Nyquist"), wxOK | wxCENTRE, mParent); return true; } if (rval == nyx_labels) { unsigned int numLabels = nyx_get_num_labels(); unsigned int l; LabelTrack *ltrack = NULL; TrackListIterator iter(mOutputTracks); for (Track *t = iter.First(); t; t = iter.Next()) { if (t->GetKind() == Track::Label) { ltrack = (LabelTrack *)t; break; } } if (!ltrack) { ltrack = mFactory->NewLabelTrack(); this->AddToOutputTracks((Track *)ltrack); } for (l = 0; l < numLabels; l++) { double t0, t1; const char *str; nyx_get_label(l, &t0, &t1, &str); ltrack->AddLabel(t0 + mT0, t1 + mT0, UTF8CTOWX(str)); } return true; } if (rval != nyx_audio) { wxMessageBox(_("Nyquist did not return audio.\n"), wxT("Nyquist"), wxOK | wxCENTRE, mParent); return false; } int outChannels; outChannels = nyx_get_audio_num_channels(); if (outChannels > mCurNumChannels) { wxMessageBox(_("Nyquist returned too many audio channels.\n"), wxT("Nyquist"), wxOK | wxCENTRE, mParent); return false; } double rate = mCurTrack[0]->GetRate(); for (i = 0; i < outChannels; i++) { sampleFormat format = mCurTrack[i]->GetSampleFormat(); if (outChannels == mCurNumChannels) { rate = mCurTrack[i]->GetRate(); } mOutputTrack[i] = mFactory->NewWaveTrack(format, rate); mCurBuffer[i] = NULL; } int success = nyx_get_audio(StaticPutCallback, (void *)this); if (!success) { for(i = 0; i < outChannels; i++) { delete mOutputTrack[i]; mOutputTrack[i] = NULL; } return false; } for (i = 0; i < outChannels; i++) { mOutputTrack[i]->Flush(); if (mCurBuffer[i]) { DeleteSamples(mCurBuffer[i]); } mOutputTime = mOutputTrack[i]->GetEndTime(); } for (i = 0; i < mCurNumChannels; i++) { WaveTrack *out; if (outChannels == mCurNumChannels) { out = mOutputTrack[i]; } else { out = mOutputTrack[0]; } mCurTrack[i]->ClearAndPaste(mT0, mT1, out, false, false); // If we were first in the group adjust non-selected group tracks if (mFirstInGroup) { SyncLockedTracksIterator git(mOutputTracks); Track *t; for (t = git.First(mCurTrack[i]); t; t = git.Next()) { if (!t->GetSelected() && t->IsSyncLockSelected()) { t->SyncLockAdjust(mT1, mT0 + out->GetEndTime()); } } } // Only the first channel can be first in its group mFirstInGroup = false; } for (i = 0; i < outChannels; i++) { delete mOutputTrack[i]; mOutputTrack[i] = NULL; } return true; }