36#include <wx/checkbox.h>
38#include <wx/datetime.h>
40#include <wx/scrolwin.h>
43#include <wx/sstream.h>
44#include <wx/stattext.h>
45#include <wx/textdlg.h>
46#include <wx/tokenzr.h>
47#include <wx/txtstrm.h>
49#include <wx/wfstream.h>
50#include <wx/numformatter.h>
51#include <wx/stdpaths.h>
54#include "../EffectManager.h"
56#include "../../LabelTrack.h"
58#include "../../NoteTrack.h"
59#include "../../TimeTrack.h"
60#include "../../prefs/SpectrogramSettings.h"
64#include "../../ShuttleAutomation.h"
65#include "../../ShuttleGetDefinition.h"
66#include "../../ShuttleGui.h"
70#include "../../WaveClip.h"
71#include "../../WaveTrack.h"
72#include "../../widgets/valnum.h"
73#include "../../widgets/AudacityMessageBox.h"
76#include "../../prefs/GUIPrefs.h"
77#include "../../tracks/playabletrack/wavetrack/ui/WaveTrackView.h"
78#include "../../tracks/playabletrack/wavetrack/ui/WaveTrackViewConstants.h"
79#include "../../widgets/NumericTextCtrl.h"
80#include "../../widgets/ProgressDialog.h"
82#include "../../widgets/FileDialog/FileDialog.h"
84#ifndef nyx_returns_start_and_end_time
85#error You need to update lib-src/libnyquist
94#define NYQUIST_WORKER_ID wxT("Nyquist Worker")
112#define NYQ_MAX_LEN (std::numeric_limits<long>::max())
114#define UNINITIALIZED_CONTROL ((double)99999999.99)
144 mOutputTrack[0] = mOutputTrack[1] =
nullptr;
146 mAction =
XO(
"Applying Nyquist Effect...");
150 mRedirectOutput =
false;
155 mReleaseVersion =
XO(
"n/a");
156 mCopyright =
XO(
"n/a");
159 mRestoreSplits =
true;
185 mName =
XO(
"Nyquist Worker");
192 mName =
Verbatim( mFileName.GetName() );
193 mFileModified = mFileName.GetModificationTime();
196 if (!mOK && mInitError.empty())
197 mInitError =
XO(
"Ill-formed Nyquist plug-in header");
226 return XO(
"Audacity");
247 ? wxString(
"Nyquist_Prompt")
257 for (
size_t i = 0, cnt = paths.size(); i < cnt; i++) {
258 fileName = wxFileName(paths[i] +
wxT(
"/") +
mHelpFile).GetFullPath();
259 if (wxFileExists(fileName))
261 return {
true, fileName };
264 return {
false, wxEmptyString };
347 visitor.
Define( d,
static_cast<const wxChar*
>( ctrl.var.c_str() ),
348 (
double)0.0, ctrl.low, ctrl.high, 1.0);
351 visitor.
Define( x,
static_cast<const wxChar*
>( ctrl.var.c_str() ), 0,
352 static_cast<int>(ctrl.low),
static_cast<int>(ctrl.high), 1);
359 visitor.
DefineEnum( x,
static_cast<const wxChar*
>( ctrl.var.c_str() ),
360 0, ctrl.choices.data(), ctrl.choices.size() );
363 visitor.
Define( ctrl.valStr, ctrl.var,
364 wxString{}, ctrl.lowStr, ctrl.highStr );
382 for (
size_t c = 0, cnt =
mControls.size(); c < cnt; c++)
395 parms.Write(ctrl.
var, d);
399 parms.Write(ctrl.
var, (
int) d);
449 pParms = &localParms;
469 const auto kTestOnly =
true;
470 const auto kTestAndSet =
false;
499 for (
size_t c = 0, cnt =
mControls.size(); c < cnt; c++)
520 good = parms.Read(ctrl.
var, &val) &&
523 if (good && !bTestOnly)
529 good = parms.Read(ctrl.
var, &val) &&
532 if (good && !bTestOnly)
533 ctrl.
val = (double)val;
542 if (good && !bTestOnly)
543 ctrl.
val = (double)val;
548 good = parms.Read(ctrl.
var, &val);
549 if (good && !bTestOnly)
558 badCount += !good ? 1 : 0;
590 bool bAllowSpectralEditing =
false;
591 bool hasSpectral =
false;
598 const auto displays = pView->GetDisplays();
599 if (displays.end() != std::find(
600 displays.begin(), displays.end(),
605 (t->GetSpectrogramSettings().SpectralSelectionEnabled())) {
606 bAllowSpectralEditing =
true;
611 if (!bAllowSpectralEditing || ((mF0 < 0.0) && (mF1 < 0.0))) {
614 XO(
"Enable track spectrogram view before\n"
615 "applying 'Spectral' effects."),
616 wxOK | wxICON_EXCLAMATION | wxCENTRE,
620 XO(
"To use 'Spectral effects', enable 'Spectral Selection'\n"
621 "in the track Spectrogram settings and select the\n"
622 "frequency range for the effect to act on."),
623 wxOK | wxICON_EXCLAMATION | wxCENTRE,
631 if (!mIsPrompt && !mExternal)
641 if (mFileName.GetModificationTime().IsLaterThan(mFileModified))
645 auto dummySettings = MakeSettings();
646 constexpr auto key = L
"TemporarySettings";
647 SaveUserPreset(
key, dummySettings);
651 mFileModified = mFileName.GetModificationTime();
654 (void) LoadUserPreset(
key, dummySettings);
667 auto cleanup =
finally([&]{
669 nyquistSettings.proxySettings = {};
673 proxy.mDebug = nyquistSettings.proxyDebug;
674 proxy.mControls = move(nyquistSettings.controls);
675 auto result =
Delegate(proxy, nyquistSettings.proxySettings);
737"error: File \"%s\" specified in header but not found in plug-in path.\n")
747 mProps += wxString::Format(
wxT(
"(putprop '*AUDACITY* (list %d %d %d) 'VERSION)\n"), AUDACITY_VERSION, AUDACITY_RELEASE, AUDACITY_REVISION);
748 wxString lang =
gPrefs->Read(
wxT(
"/Locale/Language"),
wxT(
""));
749 lang = (lang.empty())
752 mProps += wxString::Format(
wxT(
"(putprop '*AUDACITY* \"%s\" 'LANGUAGE)\n"), lang);
754 mProps += wxString::Format(
wxT(
"(setf *DECIMAL-SEPARATOR* #\\%c)\n"), wxNumberFormatter::GetDecimalSeparator());
762 mProps += wxString::Format(
wxT(
"(putprop '*SYSTEM-DIR* \"%s\" 'HOME)\n"),
EscapeString(wxGetHomeDir()));
766 for (
size_t i = 0, cnt = paths.size(); i < cnt; i++)
770 list = list.RemoveLast();
772 mProps += wxString::Format(
wxT(
"(putprop '*SYSTEM-DIR* (list %s) 'PLUGIN)\n"), list);
773 mProps += wxString::Format(
wxT(
"(putprop '*SYSTEM-DIR* (list %s) 'PLUG-IN)\n"), list);
774 mProps += wxString::Format(
wxT(
"(putprop '*SYSTEM-DIR* \"%s\" 'USER-PLUG-IN)\n"),
778 wxDateTime now = wxDateTime::Now();
779 int year = now.GetYear();
780 int doy = now.GetDayOfYear();
781 int dom = now.GetDay();
783 wxDateTime::Month month = now.GetMonth();
784 wxDateTime::WeekDay day = now.GetWeekDay();
787 mProps += wxString::Format(
wxT(
"(setf *SYSTEM-TIME* (list %d %d %d %d %d))\n"),
788 year, doy, now.GetHour(), now.GetMinute(), now.GetSecond());
790 mProps += wxString::Format(
wxT(
"(putprop '*SYSTEM-TIME* \"%s\" 'DATE)\n"), now.FormatDate());
791 mProps += wxString::Format(
wxT(
"(putprop '*SYSTEM-TIME* \"%s\" 'TIME)\n"), now.FormatTime());
792 mProps += wxString::Format(
wxT(
"(putprop '*SYSTEM-TIME* \"%s\" 'ISO-DATE)\n"), now.FormatISODate());
793 mProps += wxString::Format(
wxT(
"(putprop '*SYSTEM-TIME* \"%s\" 'ISO-TIME)\n"), now.FormatISOTime());
794 mProps += wxString::Format(
wxT(
"(putprop '*SYSTEM-TIME* %d 'YEAR)\n"), year);
795 mProps += wxString::Format(
wxT(
"(putprop '*SYSTEM-TIME* %d 'DAY)\n"), dom);
796 mProps += wxString::Format(
wxT(
"(putprop '*SYSTEM-TIME* %d 'MONTH)\n"), month);
797 mProps += wxString::Format(
wxT(
"(putprop '*SYSTEM-TIME* \"%s\" 'MONTH-NAME)\n"), now.GetMonthName(month));
798 mProps += wxString::Format(
wxT(
"(putprop '*SYSTEM-TIME* \"%s\" 'DAY-NAME)\n"), now.GetWeekDayName(day));
800 mProps += wxString::Format(
wxT(
"(putprop '*PROJECT* %d 'PROJECTS)\n"),
802 mProps += wxString::Format(
wxT(
"(putprop '*PROJECT* \"%s\" 'NAME)\n"),
EscapeString(project->GetProjectName()));
809 wxString waveTrackList;
813 for (
auto t : countRange) {
816 if (t->GetSelected())
817 waveTrackList += wxString::Format(
wxT(
"%d "), 1 + numTracks);
822 #if defined(USE_MIDI)
832 mProps += wxString::Format(
wxT(
"(putprop '*PROJECT* (float %s) 'RATE)\n"),
834 mProps += wxString::Format(
wxT(
"(putprop '*PROJECT* %d 'TRACKS)\n"), numTracks);
835 mProps += wxString::Format(
wxT(
"(putprop '*PROJECT* %d 'WAVETRACKS)\n"), numWave);
836 mProps += wxString::Format(
wxT(
"(putprop '*PROJECT* %d 'LABELTRACKS)\n"), numLabel);
837 mProps += wxString::Format(
wxT(
"(putprop '*PROJECT* %d 'MIDITRACKS)\n"), numMidi);
838 mProps += wxString::Format(
wxT(
"(putprop '*PROJECT* %d 'TIMETRACKS)\n"), numTime);
840 double previewLen = 6.0;
841 gPrefs->Read(
wxT(
"/AudioIO/EffectsPreviewLen"), &previewLen);
842 mProps += wxString::Format(
wxT(
"(putprop '*PROJECT* (float %s) 'PREVIEW-DURATION)\n"),
847 mProps += wxString::Format(
wxT(
"(setf *PREVIEWP* %s)\n"), isPreviewing);
849 mProps += wxString::Format(
wxT(
"(putprop '*SELECTION* (float %s) 'START)\n"),
851 mProps += wxString::Format(
wxT(
"(putprop '*SELECTION* (float %s) 'END)\n"),
853 mProps += wxString::Format(
wxT(
"(putprop '*SELECTION* (list %s) 'TRACKS)\n"), waveTrackList);
859 auto message =
XO(
"Audio selection required.");
862 wxOK | wxCENTRE | wxICON_EXCLAMATION,
863 XO(
"Nyquist Error") );
866 std::optional<TrackIterRange<WaveTrack>> pRange;
874 Track *gtLast = NULL;
877 bOnePassTool || pRange->first != pRange->second;
878 (void) (!pRange || (++pRange->first,
true))
884 mCurTrack[0] = pRange ? *pRange->first :
nullptr;
886 if ( (
mT1 >=
mT0) || bOnePassTool ) {
891 if (channels.size() > 1) {
901"Sorry, cannot apply effect on stereo tracks where the tracks don't match."),
919 float hours = (float)
NYQ_MAX_LEN / (44100 * 60 * 60);
922"Selection too long for Nyquist code.\nMaximum allowed selection is %ld samples\n(about %.1f hours at 44100 Hz sample rate).")
927 XO(
"Nyquist Error") );
948 wxString prevlocale = wxSetlocale(LC_NUMERIC, NULL);
949 wxSetlocale(LC_NUMERIC, wxString(
wxT(
"C")));
955 auto cleanup =
finally( [&] {
956 nyx_capture_output(NULL, (
void *)NULL);
957 nyx_set_os_callback(NULL, (
void *)NULL);
965 wxString lowHz =
wxT(
"nil");
966 wxString highHz =
wxT(
"nil");
967 wxString centerHz =
wxT(
"nil");
968 wxString bandwidth =
wxT(
"nil");
970#if defined(EXPERIMENTAL_SPECTRAL_EDITING)
979 if ((mF0 >= 0.0) && (mF1 >= 0.0)) {
983 if ((mF0 > 0.0) && (mF1 >= mF0)) {
986 double bw = log(mF1 / mF0) / log(2.0);
987 if (!std::isinf(bw)) {
993 mPerTrackProps += wxString::Format(
wxT(
"(putprop '*SELECTION* %s 'LOW-HZ)\n"), lowHz);
994 mPerTrackProps += wxString::Format(
wxT(
"(putprop '*SELECTION* %s 'CENTER-HZ)\n"), centerHz);
995 mPerTrackProps += wxString::Format(
wxT(
"(putprop '*SELECTION* %s 'HIGH-HZ)\n"), highHz);
996 mPerTrackProps += wxString::Format(
wxT(
"(putprop '*SELECTION* %s 'BANDWIDTH)\n"), bandwidth);
1002 wxSetlocale(LC_NUMERIC, prevlocale);
1004 if (!success || bOnePassTool) {
1025 XO(
"Debug Output: "),
1027 dlog.CentreOnParent();
1032 if( !bOnePassTool && ( nEffectsSoFar ==
nEffectsDone ))
1040 mT0 = selectedRegion.t0();
1041 mT1 = selectedRegion.t1();
1061 int res = wxID_APPLY;
1065 parent,
factory, pInstance, access, forceModal);
1093 auto newAccess = std::make_shared<SimpleEffectSettingsAccess>(newSettings);
1104 parent,
factory, pNewInstance, *newAccess, forceModal);
1115 parent,
factory, pNewInstance, *newAccess,
false );
1122 nyquistSettings.proxySettings = std::move(newSettings);
1123 nyquistSettings.proxyDebug = this->
mDebug;
1124 nyquistSettings.controls = move(effect.
mControls);
1196 cmd +=
wxT(
"(snd-set-latency 0.1)");
1201 cmd +=
wxT(
"(setf S 0.25)\n");
1203 nyx_set_audio_name(
"*TRACK*");
1204 cmd +=
wxT(
"(setf S 0.25)\n");
1207 nyx_set_audio_name(
"S");
1208 cmd +=
wxT(
"(setf *TRACK* '*unbound*)\n");
1221 wxString spectralEditp;
1231 auto displays = pView->GetDisplays();
1232 auto format = [&](
decltype(displays[0]) display ) {
1235 return wxString::Format(
wxT(
"\"%s\""),
1236 display.name.Stripped().Debug() );
1238 if (displays.empty())
1240 else if (displays.size() == 1)
1241 view =
format( displays[0] );
1243 view =
wxT(
"(list");
1244 for (
auto display : displays )
1245 view += wxString(
wxT(
" ")) +
format( display );
1250#if defined(USE_MIDI)
1253 view =
wxT(
"\"Midi\"");
1257 type =
wxT(
"label");
1258 view =
wxT(
"\"Label\"");
1262 view =
wxT(
"\"Time\"");
1266 cmd += wxString::Format(
wxT(
"(putprop '*TRACK* %d 'INDEX)\n"), ++
mTrackIndex);
1268 cmd += wxString::Format(
wxT(
"(putprop '*TRACK* \"%s\" 'TYPE)\n"), type);
1270 cmd += wxString::Format(
wxT(
"(putprop '*TRACK* %s 'VIEW)\n"), view);
1274 cmd += wxString::Format(
wxT(
"(putprop '*TRACK* %s 'SPECTRAL-EDIT-ENABLED)\n"), spectralEditp);
1280 cmd += wxString::Format(
wxT(
"(putprop '*TRACK* (float %s) 'START-TIME)\n"),
1282 cmd += wxString::Format(
wxT(
"(putprop '*TRACK* (float %s) 'END-TIME)\n"),
1284 cmd += wxString::Format(
wxT(
"(putprop '*TRACK* (float %s) 'GAIN)\n"),
1286 cmd += wxString::Format(
wxT(
"(putprop '*TRACK* (float %s) 'PAN)\n"),
1288 cmd += wxString::Format(
wxT(
"(putprop '*TRACK* (float %s) 'RATE)\n"),
1291 switch (
mCurTrack[0]->GetSampleFormat())
1294 bitFormat =
wxT(
"16");
1297 bitFormat =
wxT(
"24");
1300 bitFormat =
wxT(
"32.0");
1303 cmd += wxString::Format(
wxT(
"(putprop '*TRACK* %s 'FORMAT)\n"), bitFormat);
1305 float maxPeakLevel = 0.0;
1306 wxString clips, peakString, rmsString;
1309 float maxPeak = 0.0;
1313 clips +=
wxT(
"(list ");
1317 for (
size_t i=0; i<ca.size(); i++) {
1319 clips += wxString::Format(
wxT(
"(list (float %s) (float %s))"),
1322 }
else if (i == 1000) {
1325 }
else if (i > 1000) {
1333 min = pair.first, max = pair.second;
1334 maxPeak = wxMax(wxMax(fabs(
min), fabs(max)), maxPeak);
1335 maxPeakLevel = wxMax(maxPeakLevel, maxPeak);
1338 if (!std::isinf(maxPeak) && !std::isnan(maxPeak) && (maxPeak < FLT_MAX)) {
1341 peakString +=
wxT(
"nil ");
1345 if (!std::isinf(rms) && !std::isnan(rms)) {
1348 rmsString +=
wxT(
"NIL ");
1352 cmd += wxString::Format(
wxT(
"(putprop '*TRACK* %s%s ) 'CLIPS)\n"),
1357 cmd += wxString::Format(
wxT(
"(putprop '*SELECTION* (vector %s) 'PEAK)\n"), peakString) :
1358 cmd += wxString::Format(
wxT(
"(putprop '*SELECTION* %s 'PEAK)\n"), peakString);
1360 if (!std::isinf(maxPeakLevel) && !std::isnan(maxPeakLevel) && (maxPeakLevel < FLT_MAX)) {
1361 cmd += wxString::Format(
wxT(
"(putprop '*SELECTION* (float %s) 'PEAK-LEVEL)\n"),
1366 cmd += wxString::Format(
wxT(
"(putprop '*SELECTION* (vector %s) 'RMS)\n"), rmsString) :
1367 cmd += wxString::Format(
wxT(
"(putprop '*SELECTION* %s 'RMS)\n"), rmsString);
1372 nyx_set_audio_params(44100, 0);
1389 cmd +=
wxT(
"(setf s 0.25)\n");
1393 cmd +=
wxT(
"(setf *tracenable* T)\n");
1395 cmd +=
wxT(
"(setf *breakenable* T)\n");
1402 cmd +=
wxT(
"(setf *tracenable* NIL)\n");
1405 for (
unsigned int j = 0; j <
mControls.size(); j++) {
1412 cmd += wxString::Format(
wxT(
"(setf %s %s)\n"),
1419 cmd += wxString::Format(
wxT(
"(setf %s %d)\n"),
1424 cmd +=
wxT(
"(setf ");
1429 cmd +=
wxT(
"\")\n");
1440 str +=
wxT(
"\nset aud:result = main()\n");
1446 cmd +=
wxT(
"(setf *tracenable* nil)\n");
1447 cmd +=
wxT(
"(setf *breakenable* nil)\n");
1448 cmd +=
wxT(
"(setf *sal-traceback* t)\n");
1452 cmd +=
wxT(
"(setf *sal-compiler-debug* t)\n");
1455 cmd +=
wxT(
"(setf *sal-call-stack* nil)\n");
1459 cmd +=
wxT(
"(setf aud:result nil)\n");
1460 cmd +=
wxT(
"(sal-compile-audacity \"") +
str +
wxT(
"\" t t nil)\n");
1464 cmd +=
wxT(
"(prog1 aud:result (setf aud:result nil))\n");
1475 auto cleanup =
finally( [&] {
1482 rval = nyx_eval_expression(cmd.mb_str(wxConvUTF8));
1488 wxLogMessage(
wxT(
"\'%s\' returned:\n%s"),
1509 XO(
"';type tool' effects cannot return audio from Nyquist.\n")
1518 XO(
"';type tool' effects cannot return labels from Nyquist.\n")
1523 if (rval == nyx_error) {
1540 if (rval == nyx_list) {
1541 wxLogMessage(
"Nyquist returned nyx_list");
1550 if (rval == nyx_string) {
1576 if (rval == nyx_double) {
1577 auto str =
XO(
"Nyquist returned the value: %f")
1578 .Format(nyx_get_double());
1583 if (rval == nyx_int) {
1584 auto str =
XO(
"Nyquist returned the value: %d")
1585 .Format(nyx_get_int());
1590 if (rval == nyx_labels) {
1592 unsigned int numLabels = nyx_get_num_labels();
1596 auto newTrack = std::make_shared<LabelTrack>();
1603 for (l = 0; l < numLabels; l++) {
1609 nyx_get_label(l, &t0, &t1, &
str);
1616 wxASSERT(rval == nyx_audio);
1618 int outChannels = nyx_get_audio_num_channels();
1624 if (outChannels == -1) {
1626 XO(
"Nyquist returned one audio channel as an array.\n") );
1630 if (outChannels == 0) {
1635 std::shared_ptr<WaveTrack> outputTrack[2];
1638 for (
int i = 0; i < outChannels; i++) {
1644 outputTrack[i]->SetRate( rate );
1664 std::rethrow_exception( pException );
1670 for (
int i = 0; i < outChannels; i++) {
1671 outputTrack[i]->Flush();
1684 out = outputTrack[i].get();
1687 out = outputTrack[0].get();
1724 wxString
str(nyqString, wxConvUTF8);
1725 if (nyqString != NULL && nyqString[0] &&
str.empty()) {
1727 str =
_(
"[Warning: Nyquist returned invalid UTF-8 string, converted here as Latin-1]");
1737 wxString
str = inStr;
1747 std::vector<EnumValueSymbol> results;
1748 if (text[0] ==
wxT(
'(')) {
1752 auto &choices = tzer.
tokens;
1754 for (
auto &choice : choices) {
1767 auto choices = wxStringTokenize(
1768 text[0] ==
wxT(
'"') ? text.Mid(1, text.length() - 2) : text,
1771 for (
auto &choice : choices)
1772 results.push_back( { choice.Trim(
true).Trim(
false) } );
1781 if (text[0] ==
wxT(
'(')) {
1784 for (
const auto &token : tzer.
tokens)
1785 results.push_back(
UnQuote( token ) );
1794 if (text[0] ==
wxT(
'(')) {
1797 auto &tokens = tzer.
tokens;
1798 if ( tokens.size() == 2 )
1809 if (text[0] ==
wxT(
'(')) {
1812 auto &types = tzer.
tokens;
1813 if ( !types.empty() && types[0][0] ==
wxT(
'(') )
1814 for (
auto &type : types)
1817 if ( results.empty() ) {
1821 auto pieces = wxSplit(
str,
'|' );
1823 auto size = pieces.size();
1824 if (
size % 2 == 1 )
1825 --
size, pieces.pop_back();
1826 for (
size_t ii = 0; ii <
size; ii += 2 ) {
1828 auto extensionStrings = wxSplit( pieces[ii + 1],
';' );
1829 for (
const auto &extensionString : extensionStrings )
1830 if ( extensionString.StartsWith(
wxT(
"*.") ) ) {
1831 auto ext = extensionString.substr( 2 );
1832 if (ext ==
wxT(
"*"))
1835 extensions.push_back( ext );
1837 results.push_back( {
Verbatim( pieces[ii] ), extensions } );
1873 wxString *pExtraString)
1876 *pExtraString = wxString{};
1878 int len = s.length();
1879 if (len >= 2 && s[0] ==
wxT(
'\"') && s[len - 1] ==
wxT(
'\"')) {
1880 auto unquoted = s.Mid(1, len - 2);
1885 else if (allowParens &&
1886 len >= 2 && s[0] ==
wxT(
'(') && s[len - 1] ==
wxT(
')')) {
1889 auto &tokens = tzer.
tokens;
1890 if (tokens.size() > 1) {
1891 if (pExtraString && tokens[1][0] ==
'(') {
1895 *pExtraString =
UnQuote(tokens[0],
false);
1914 wxString *pExtraString)
1938 const wxString &line,
bool eof,
1939 size_t trimStart,
size_t trimEnd)
1941 auto endToken = [&]{
1950 if (
q && !
sl && c ==
wxT(
'\\')) {
1956 if (!
sl && c ==
wxT(
'"')) {
1976 else if (!
q && !
paren && (c ==
wxT(
' ') || c ==
wxT(
'\t')))
1980 else if (!
q && c ==
wxT(
';'))
1986 else if (!
q && c ==
wxT(
'(')) {
1990 endToken(),
tok += c;
1995 else if (!
q && c ==
wxT(
')')) {
1999 tok += c, endToken();
2002 paren = 0, endToken();
2023 if (eof || (!
q && !
paren)) {
2037 Tokenizer &tzer,
const wxString &line,
bool eof,
bool first)
2039 if ( !tzer.
Tokenize(line, eof, first ? 1 : 0, 0) )
2042 const auto &tokens = tzer.
tokens;
2043 int len = tokens.size();
2050 if (len == 2 && tokens[0] ==
wxT(
"nyquist") &&
2051 (tokens[1] ==
wxT(
"plug-in") || tokens[1] ==
wxT(
"plugin"))) {
2056 if (len >= 2 && tokens[0] ==
wxT(
"type")) {
2057 wxString tok = tokens[1];
2059 if (tok ==
wxT(
"tool")) {
2073 if (tok ==
wxT(
"process")) {
2076 else if (tok ==
wxT(
"generate")) {
2079 else if (tok ==
wxT(
"analyze")) {
2083 if (len >= 3 && tokens[2] ==
wxT(
"spectral")) {;
2089 if (len == 2 && tokens[0] ==
wxT(
"codetype")) {
2091 if (tokens[1] ==
wxT(
"lisp")) {
2095 else if (tokens[1] ==
wxT(
"sal")) {
2102 if (len >= 2 && tokens[0] ==
wxT(
"debugflags")) {
2103 for (
int i = 1; i < len; i++) {
2106 if (tokens[i] ==
wxT(
"trace")) {
2109 else if (tokens[i] ==
wxT(
"notrace")) {
2112 else if (tokens[i] ==
wxT(
"compiler")) {
2115 else if (tokens[i] ==
wxT(
"nocompiler")) {
2126 if (len >= 2 && tokens[0] ==
wxT(
"version")) {
2128 tokens[1].ToLong(&v);
2129 if (v < 1 || v > 4) {
2133"This version of Audacity does not support Nyquist plug-in version %ld")
2140 if (len >= 2 && tokens[0] ==
wxT(
"name")) {
2150 if (
name.EndsWith(
wxT(
"...")))
2156 if (len >= 2 && tokens[0] ==
wxT(
"action")) {
2161 if (len >= 2 && tokens[0] ==
wxT(
"info")) {
2166 if (len >= 2 && tokens[0] ==
wxT(
"preview")) {
2167 if (tokens[1] ==
wxT(
"enabled") || tokens[1] ==
wxT(
"true")) {
2171 else if (tokens[1] ==
wxT(
"linear")) {
2175 else if (tokens[1] ==
wxT(
"selection")) {
2179 else if (tokens[1] ==
wxT(
"disabled") || tokens[1] ==
wxT(
"false")) {
2187 if (len >= 2 && tokens[0] ==
wxT(
"maxlen")) {
2189 tokens[1].ToLongLong(&v);
2193#if defined(EXPERIMENTAL_NYQUIST_SPLIT_CONTROL)
2194 if (len >= 2 && tokens[0] ==
wxT(
"mergeclips")) {
2197 tokens[1].ToLong(&v);
2202 if (len >= 2 && tokens[0] ==
wxT(
"restoresplits")) {
2205 tokens[1].ToLong(&v);
2211 if (len >= 2 && tokens[0] ==
wxT(
"author")) {
2216 if (len >= 2 && tokens[0] ==
wxT(
"release")) {
2223 if (len >= 2 && tokens[0] ==
wxT(
"copyright")) {
2229 if (len >= 2 && tokens[0] ==
wxT(
"manpage")) {
2236 if (len >= 2 && tokens[0] ==
wxT(
"helpfile")) {
2243 if (len >= 2 && tokens[0] ==
wxT(
"debugbutton")) {
2244 if (tokens[1] ==
wxT(
"disabled") || tokens[1] ==
wxT(
"false")) {
2251 if (len >= 3 && tokens[0] ==
wxT(
"control")) {
2254 if (len == 3 && tokens[1] ==
wxT(
"text")) {
2255 ctrl.
var = tokens[1];
2261 ctrl.
var = tokens[1];
2264 ctrl.
label = tokens[4];
2267 ctrl.
valStr = len > 5 ? tokens[5] : wxString{};
2269 if (ctrl.
valStr.length() > 0 &&
2277 if (tokens[3] ==
wxT(
"string")) {
2281 else if (tokens[3] ==
wxT(
"choice")) {
2286 else if (tokens[3] ==
wxT(
"file")) {
2300 if ((tokens[3] ==
wxT(
"float")) ||
2301 (tokens[3] ==
wxT(
"real")))
2303 else if (tokens[3] ==
wxT(
"int"))
2305 else if (tokens[3] ==
wxT(
"float-text"))
2307 else if (tokens[3] ==
wxT(
"int-text"))
2309 else if (tokens[3] ==
wxT(
"time"))
2314 str.Printf(
wxT(
"Bad Nyquist 'control' type specification: '%s' in plug-in file '%s'.\nControl not created."),
2334 ctrl.
low = -(FLT_MAX);
2345 ctrl.
high = INT_MAX;
2350 ctrl.
high = FLT_MAX;
2360 if (ctrl.
val < ctrl.
low) {
2383 if (len >= 2 && tokens[0] ==
wxT(
"categories")) {
2384 for (
size_t i = 1; i < tokens.size(); ++i) {
2399 wxTextInputStream pgm(stream,
wxT(
" \t"), wxConvAuto());
2421 while (!stream.Eof() && stream.IsOk())
2423 wxString line = pgm.ReadLine();
2424 if (line.length() > 1 &&
2428 (line[0] ==
wxT(
';') || line[0] ==
wxT(
'$')) )
2431 unsigned nLines = 1;
2435 line[0] ==
wxT(
'$') || line.StartsWith(
wxT(
";control") );
2437 done =
Parse(tzer, line, !control || stream.Eof(), nLines == 1);
2439 (line = pgm.ReadLine(), ++nLines,
true));
2450 if (line[0] ==
wxT(
'(') ||
2451 (line[0] ==
wxT(
'#') && line.length() > 1 && line[1] ==
wxT(
'|')))
2456 else if (line.Upper().Find(
wxT(
"RETURN")) != wxNOT_FOUND)
2471"Your code looks like SAL syntax, but there is no \'return\' statement.\n\
2472For SAL, use a return statement such as:\n\treturn *track* * 0.1\n\
2473or for LISP, begin with an open parenthesis such as:\n\t(mult *track* 0.1)\n ."),
2475 XO(
"Error in Nyquist code") );
2491 wxFileInputStream rawStream(
mFileName.GetFullPath());
2492 wxBufferedInputStream stream(rawStream, 10000);
2499 wxStringInputStream stream(cmd +
wxT(
" "));
2505 int64_t start, int64_t len, int64_t totlen,
2509 return This->
GetCallback(buffer, channel, start, len, totlen);
2513 int64_t start, int64_t len, int64_t WXUNUSED(totlen))
2553 std::memcpy(buffer, src, len *
sizeof(
float));
2556 double progress =
mScale *
2572 int64_t start, int64_t len, int64_t totlen,
2576 return This->
PutCallback(buffer, channel, start, len, totlen);
2580 int64_t start, int64_t len, int64_t totlen)
2583 return GuardedCall<int>( [&] {
2585 double progress =
mScale*((float)(start+len)/totlen);
2615 std::cout << (char)c;
2648#if defined(__WXMAC__)
2658 for (
size_t i = 0; i < audacityPathList.size(); i++)
2660 wxString prefix = audacityPathList[i] + wxFILE_SEP_PATH;
2679 for (
size_t i = 0, cnt =
mControls.size(); i < cnt; i++)
2685 const auto count = ctrl.
choices.size();
2687 int val = (int)ctrl.
val;
2688 if (val < 0 || val >= (
int)count)
2694 c->SetSelection(val);
2699 double range = ctrl.
high - ctrl.
low;
2700 int val = (int)(0.5 + ctrl.
ticks * (ctrl.
val - ctrl.
low) / range);
2720 const wxString left =
wxT(
"\u201c"), right =
wxT(
"\u201d"), dumb =
'"';
2724 const wxString leftSingle =
wxT(
"\u2018"), rightSingle =
wxT(
"\u2019"),
2726 mInputCmd.Replace(leftSingle, dumbSingle,
true);
2727 mInputCmd.Replace(rightSingle, dumbSingle,
true);
2739 for (
unsigned int i = 0; i <
mControls.size(); i++)
2763 if (ctrl->
valStr.StartsWith(
"\"", &path))
2766 if (path.EndsWith(
"\"", &path))
2768 path.Replace(
"\"\"",
"\"");
2769 wxStringTokenizer tokenizer(path,
"\"");
2770 while (tokenizer.HasMoreTokens())
2772 wxString token = tokenizer.GetNextToken();
2775 const auto message =
2776 XO(
"\"%s\" is not a valid file path.").Format( token );
2779 wxOK | wxICON_EXCLAMATION | wxCENTRE,
2788 const auto message =
2790 XO(
"Mismatched quotes in\n%s").Format( ctrl->
valStr );
2793 wxOK | wxICON_EXCLAMATION | wxCENTRE,
2805 const auto message =
2806 XO(
"\"%s\" is not a valid file path.").Format( ctrl->
valStr );
2809 wxOK | wxICON_EXCLAMATION | wxCENTRE,
2821 ctrl->
low = INT_MIN;
2824 ctrl->
lowStr.IsSameAs(
wxT(
"nil"),
false))
2826 ctrl->
low = -(FLT_MAX);
2834 ctrl->
high = INT_MAX;
2839 ctrl->
high = FLT_MAX;
2851 if (ctrl->
val < ctrl->
low)
2874 S.StartVerticalLay();
2876 S.StartMultiColumn(3, wxEXPAND);
2878 S.SetStretchyCol(1);
2880 S.AddVariableText(
XO(
"Enter Nyquist Command: "));
2886 S.StartHorizontalLay(wxEXPAND, 1);
2889 .MinSize( { 500, 200 } )
2890 .AddTextWindow(
wxT(
""));
2892 S.EndHorizontalLay();
2894 S.StartHorizontalLay(wxALIGN_CENTER, 0);
2899 S.EndHorizontalLay();
2906 wxScrolledWindow *scroller =
S.Style(wxVSCROLL | wxTAB_TRAVERSAL)
2909 S.StartMultiColumn(4);
2911 for (
size_t i = 0; i <
mControls.size(); i++)
2918 S.StartHorizontalLay(wxALIGN_LEFT, 0);
2923 S.EndHorizontalLay();
2924 S.StartMultiColumn(4);
2928 auto prompt =
XXO(
"%s:").Format( ctrl.
name );
2929 S.AddPrompt( prompt );
2936 .Validator<wxGenericValidator>(&ctrl.
valStr)
2938 .AddTextBox( {},
wxT(
""), 50);
2965 .Position(wxALIGN_LEFT | wxALL)
2976 if ( !type.extensions.empty() )
2977 defaultExtension = type.extensions[0];
2983 .AddTextBox( {},
wxT(
""), 40);
2984 item->SetValidator(wxGenericValidator(&ctrl.
valStr));
2986 if (ctrl.
label.empty())
2988 ctrl.
label = wxGetTranslation( wxFileSelectorPromptStr );
3003 double range = ctrl.
high - ctrl.
low;
3004 S.Validator<FloatingPointValidator<double>>(
3009 ? NumValidatorStyle::THREE_TRAILING_ZEROES
3011 ? NumValidatorStyle::TWO_TRAILING_ZEROES
3012 : NumValidatorStyle::ONE_TRAILING_ZERO),
3018 S.Validator<IntegerValidator<double>>(
3019 &ctrl.
val, NumValidatorStyle::DEFAULT,
3020 (int) ctrl.
low, (
int) ctrl.
high);
3022 wxTextCtrl *item =
S
3024 .AddTextBox( {},
wxT(
""),
3031 .Style(wxSL_HORIZONTAL)
3032 .MinSize( { 150, -1 } )
3033 .AddSlider( {}, 0, ctrl.
ticks, 0);
3055 scroller->SetScrollRate(0, 20);
3058 scroller->SetName(
wxT(
"\a"));
3059 scroller->SetLabel(
wxT(
"\a"));
3081 XO(
"Current program has been modified.\nDiscard changes?"),
3090 XO(
"Load Nyquist script"),
3096 FileNames::TextFiles,
3099 wxFD_OPEN | wxRESIZE_BORDER);
3118 XO(
"Save Nyquist script"),
3126 wxFD_SAVE | wxFD_OVERWRITE_PROMPT | wxRESIZE_BORDER);
3146 int val = evt.GetInt();
3147 double range = ctrl.
high - ctrl.
low;
3148 double newVal = (val / (double)ctrl.
ticks) * range + ctrl.
low;
3151 int precision = range < 1.0 ? 3 :
3159 if (fabs(newVal - ctrl.
val) >= (1 / (double)ctrl.
ticks) * range &&
3160 fabs(newVal - ctrl.
val) >= pow(0.1, precision) / 2)
3163 newVal *= pow(10.0, precision);
3164 newVal = floor(newVal + 0.5);
3165 newVal /= pow(10.0, precision);
3180 int i = evt.GetId() -
ID_Time;
3181 static double value = 0.0;
3190 if (val < ctrl.low || val > ctrl.
high) {
3191 const auto message =
XO(
"Value range:\n%s to %s")
3196 XO(
"Value Error") );
3201 else if (val > ctrl.
high)
3211 int i = evt.GetId() -
ID_FILE;
3216 unsigned int flags = 0;
3219 wxStringTokenizer tokenizer(ctrl.
highStr,
",");
3220 while ( tokenizer.HasMoreTokens() )
3222 wxString token = tokenizer.GetNextToken().Trim(
true).Trim(
false);
3223 if (token.IsSameAs(
"open",
false))
3226 flags &= ~wxFD_SAVE;
3227 flags &= ~wxFD_OVERWRITE_PROMPT;
3229 else if (token.IsSameAs(
"save",
false))
3232 flags &= ~wxFD_OPEN;
3233 flags &= ~wxFD_MULTIPLE;
3234 flags &= ~wxFD_FILE_MUST_EXIST;
3236 else if (token.IsSameAs(
"overwrite",
false) && !(flags & wxFD_OPEN))
3238 flags |= wxFD_OVERWRITE_PROMPT;
3240 else if (token.IsSameAs(
"exists",
false) && !(flags & wxFD_SAVE))
3242 flags |= wxFD_FILE_MUST_EXIST;
3244 else if (token.IsSameAs(
"multiple",
false) && !(flags & wxFD_SAVE))
3246 flags |= wxFD_MULTIPLE;
3253 wxFileName fname = ctrl.
valStr;
3254 wxString defaultDir = fname.GetPath();
3255 wxString defaultFile = fname.GetName();
3256 auto message =
XO(
"Select a file");
3258 if (flags & wxFD_MULTIPLE)
3259 message =
XO(
"Select one or more files");
3260 else if (flags & wxFD_SAVE)
3261 message =
XO(
"Save file as");
3270 if (openFileDialog.
ShowModal() == wxID_CANCEL)
3277 if (flags & wxFD_MULTIPLE)
3279 wxArrayString selectedFiles;
3280 openFileDialog.
GetPaths(selectedFiles);
3282 for (
size_t sf = 0; sf < selectedFiles.size(); sf++) {
3284 path += selectedFiles[sf];
3307#if defined(__WXMSW__)
3308 path.Replace(
"/", wxFileName::GetPathSeparator());
3311 path.Trim(
true).Trim(
false);
3313 typedef std::unordered_map<wxString, FilePath> map;
3315 {
"*home*", wxGetHomeDir()},
3316 {
"~", wxGetHomeDir()},
3323 int characters = path.Find(wxFileName::GetPathSeparator());
3324 if(characters == wxNOT_FOUND)
3329 if (pathKeys.find(path) != pathKeys.end())
3332 path = pathKeys[path] + wxFileName::GetPathSeparator();
3336 path = pathKeys[
"*default*"] + wxFileName::GetPathSeparator() + path;
3341 wxString firstDir = path.Left(characters);
3342 wxString rest = path.Mid(characters);
3344 if (pathKeys.find(firstDir) != pathKeys.end())
3346 path = pathKeys[firstDir] + rest;
3350 wxFileName fname = path;
3354 if (fname.wxFileName::IsOk() && fname.GetFullName().empty())
3356 path = fname.GetPathWithSep() +
_(
"untitled");
3357 if (!extension.empty())
3358 path = path +
'.' + extension;
3365 wxFileName fname = path;
3366 wxString dir = fname.GetPath();
3368 return (fname.wxFileName::IsOk() &&
3369 wxFileName::DirExists(dir) &&
3370 !fname.GetFullName().empty());
3376 int seconds =
static_cast<int>(t);
3377 int hh = seconds / 3600;
3378 int mm = seconds % 3600;
3380 return wxString::Format(
"%d:%d:%.3f", hh, mm, t - (hh * 3600 + mm * 60));
3386 int i = evt.GetId() -
ID_Text;
3390 if (wxDynamicCast(evt.GetEventObject(), wxWindow)->GetValidator()->TransferFromWindow())
3394 int pos = (int)floor((ctrl.
val - ctrl.
low) /
3398 slider->SetValue(pos);
3418:
wxDialogWrapper{ parent,
id,
title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER }
3426 S.AddVariableText( prompt,
false, wxALIGN_LEFT | wxLEFT | wxTOP | wxRIGHT );
3431 .Position(wxEXPAND | wxALL)
3432 .MinSize( { 480, 250 } )
3433 .Style(wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH)
3434 .AddTextWindow( message.Translation() );
3438 S.StartHorizontalLay(wxALIGN_CENTRE | wxLEFT | wxBOTTOM | wxRIGHT, 0 );
3441 S.Id(wxID_OK).AddButton(
XXO(
"OK"), wxALIGN_CENTRE,
true );
3443 S.EndHorizontalLay();
3447 SetAutoLayout(
true);
3448 GetSizer()->Fit(
this);
3449 GetSizer()->SetSizeHints(
this);
3462#include "../../../lib-src/libnyquist/nyquist/xlisp/xlisp.h"
3466 auto string =
UTF8CTOWX(getstring(xlgastring()));
3467#if !HAS_I18N_CONTEXTS
3478#if HAS_I18N_CONTEXTS
3479 auto string =
UTF8CTOWX(getstring(xlgastring()));
3480 auto context =
UTF8CTOWX(getstring(xlgastring()));
3482 return cvstring(wxGetTranslation(
string,
"", 0,
"", context )
3483 .mb_str(wxConvUTF8));
3491 auto string1 =
UTF8CTOWX(getstring(xlgastring()));
3492 auto string2 =
UTF8CTOWX(getstring(xlgastring()));
3493 auto number = getfixnum(xlgafixnum());
3494#if !HAS_I18N_CONTEXTS
3501 wxGetTranslation(string1, string2, number).mb_str(wxConvUTF8));
3506#if HAS_I18N_CONTEXTS
3507 auto string1 =
UTF8CTOWX(getstring(xlgastring()));
3508 auto string2 =
UTF8CTOWX(getstring(xlgastring()));
3509 auto number = getfixnum(xlgafixnum());
3510 auto context =
UTF8CTOWX(getstring(xlgastring()));
3512 return cvstring(wxGetTranslation( string1, string2, number,
"", context )
3513 .mb_str(wxConvUTF8));
3521 unsigned char * dstp;
3522 dst = new_string((
int)(
size+2));
3523 dstp = getstring(dst);
3537 wxString Left = Str.BeforeLast(
'\n').BeforeLast(
'\n').ToAscii();
3538 wxString Right = Str.BeforeLast(
'\n').AfterLast(
'\n').ToAscii();
3539 message = cvstring(Left);
3540 success = Right.EndsWith(
"OK") ? s_true :
nullptr;
3541 dst = cons(message, success);
3545#include "../../commands/ScriptCommandRelay.h"
3553 unsigned char *leftp;
3561 leftp = getstring(src);
3575 static bool firstTime =
true;
3580 static const FUNDEF functions[] = {
3588 xlbindfunctions( functions, WXSIZEOF( functions ) );
wxEVT_COMMAND_BUTTON_CLICKED
SimpleGuard< R > MakeSimpleGuard(R value) noexcept(noexcept(SimpleGuard< R >{ value }))
Convert a value to a handler function returning that value, suitable for GuardedCall<R>
Toolkit-neutral facade for basic user interface services.
static const AudacityProject::AttachedObjects::RegisteredFactory key
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
const TranslatableString name
#define NYQUISTEFFECTS_FAMILY
std::function< DialogFactoryResults(wxWindow &parent, EffectPlugin &, EffectUIClientInterface &, EffectSettingsAccess &) > EffectDialogFactory
Type of function that creates a dialog for an effect.
XXO("&Cut/Copy/Paste Toolbar")
wxString FileExtension
File extension, not including any leading dot.
wxString PluginPath
type alias for identifying a Plugin supplied by a module, each module defining its own interpretation...
STRINGS_API const wxString & GetCustomTranslation(const wxString &str1)
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
#define UNINITIALIZED_CONTROL
void * nyq_make_opaque_string(int size, unsigned char *src)
void * nyq_reformat_aud_do_response(const wxString &Str)
static const FileNames::FileType LispScripts
wxEVT_COMMAND_TEXT_UPDATED
static const wxChar * KEY_Command
static const FileNames::FileType NyquistScripts
EVT_COMMAND_RANGE(ID_Slider, ID_Slider+99, wxEVT_COMMAND_SLIDER_UPDATED, NyquistEffect::OnSlider) EVT_COMMAND_RANGE(ID_Text
#define NYQUIST_WORKER_ID
static const wxChar * KEY_Parameters
NyquistEffect::OnText ID_Time
static void RegisterFunctions()
#define NYQUIST_PROMPT_ID
#define NYQUIST_PROMPT_NAME
an object holding per-project preferred sample rate
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
void * ExecForLisp(char *pIn)
TranslatableStrings Msgids(const EnumValueSymbol strings[], size_t nStrings)
Convenience function often useful when adding choice controls.
static Settings & settings()
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
CommandParameters, derived from wxFileConfig, is essentially doing the same things as the SettingsVis...
bool WriteEnum(const wxString &key, int value, const EnumValueSymbol choices[], size_t nChoices)
bool GetParameters(wxString &parms)
bool ReadEnum(const wxString &key, int *pi, const EnumValueSymbol choices[], size_t nChoices, const ObsoleteMap obsoletes[]=nullptr, size_t nObsoletes=0) const
bool SetParameters(const wxString &parms)
TranslatableString GetName() const
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
std::shared_ptr< TrackList > mOutputTracks
void SetPreviewFullSelectionFlag(bool previewDurationFlag)
bool IsPreviewing() const
void SetLinearEffectFlag(bool linearEffectFlag)
const TrackList * inputTracks() const
wxArrayString mPresetNames
void ReplaceProcessedTracks(const bool bGoodResult)
const AudacityProject * FindProject() const
bool TrackGroupProgress(int whichGroup, double frac, const TranslatableString &={}) const
void SetBatchProcessing() override
void CopyInputTracks(bool allSyncLockSelected=false)
int MessageBox(const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={}) const
virtual NumericFormatSymbol GetSelectionFormat()
int ShowHostInterface(wxWindow &parent, const EffectDialogFactory &factory, std::shared_ptr< EffectInstance > &pInstance, EffectSettingsAccess &access, bool forceModal=false) override
Usually applies factory to self and given access.
bool TotalProgress(double frac, const TranslatableString &={}) const
Track * AddToOutputTracks(const std::shared_ptr< Track > &t)
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
bool IsBatchProcessing() const override
bool Delegate(Effect &delegate, EffectSettings &settings)
Re-invoke DoEffect on another Effect object that implements the work.
unsigned TestUIFlags(unsigned mask)
int GetNumWaveGroups() const
Performs effect computation.
EffectManager is the class that handles effects and effect categories.
void SetSkipStateFlag(bool flag)
static EffectManager & Get()
Hold values to send to effect output meters.
void ModifySettings(Function &&function)
Do a correct read-modify-write of settings.
static bool EnablePreview(wxWindow *parent, bool enable=true)
static NyquistSettings & GetSettings(EffectSettings &settings)
Assume settings originated from MakeSettings() and copies thereof.
EffectSettings MakeSettings() const override
virtual wxString GetPath() const
virtual void GetPaths(wxArrayString &paths) const
std::vector< FileType > FileTypes
static wxString ToString(double numberToConvert, int digitsAfterDecimalPoint=-1)
Convert a number to a string, always uses the dot as decimal separator.
static bool CompatibleToDouble(const wxString &stringToConvert, double *result)
Convert a string to a number.
A LabelTrack is a Track that holds labels (LabelStruct).
static wxString GetDefaultName()
A Track that is used for Midi notes. (Somewhat old code).
void SetValue(double newValue)
A control on a NyquistDialog.
std::vector< EnumValueSymbol > choices
FileNames::FileTypes fileTypes
An Effect that calls up a Nyquist (XLISP) plug-in, i.e. many possible effects from this one class.
bool Process(EffectInstance &instance, EffectSettings &settings) override
static TranslatableString UnQuoteMsgid(const wxString &s, bool allowParens=true, wxString *pExtraString=nullptr)
TranslatableString GetDescription() const override
wxWeakRef< wxWindow > mUIParent
int GetCallback(float *buffer, int channel, int64_t start, int64_t len, int64_t totlen)
static double GetCtrlValue(const wxString &s)
wxTextCtrl * mCommandText
bool ParseCommand(const wxString &cmd)
TranslatableString mDebugOutput
std::pair< bool, FilePath > CheckHelpPage() const
bool TransferDataFromPromptWindow()
TranslatableString mCopyright
bool TransferDataFromWindow(EffectSettings &settings) override
Update the given settings from controls.
TranslatableString mPromptName
bool SaveSettings(const EffectSettings &settings, CommandParameters &parms) const override
Store settings as keys and values.
std::unique_ptr< EffectUIValidator > PopulateOrExchange(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) override
Add controls to effect panel; always succeeds.
void OutputCallback(int c)
std::exception_ptr mpException
bool Parse(Tokenizer &tokenizer, const wxString &line, bool eof, bool first)
FileExtensions ParseFileExtensions(const wxString &text)
void BuildEffectWindow(ShuttleGui &S)
bool IsDefault() const override
Whether the effect sorts "above the line" in the menus.
ManualPageID ManualPage() const override
Name of a page in the Audacity alpha manual, default is empty.
EffectFamilySymbol GetFamily() const override
Report identifier and user-visible name of the effect protocol.
bool ParseProgram(wxInputStream &stream)
static void StaticOSCallback(void *userdata)
bool DoLoadSettings(const CommandParameters &parms, EffectSettings &settings)
int SetLispVarsFromParameters(const CommandParameters &parms, bool bTestOnly)
void OnLoad(wxCommandEvent &evt)
bool EnablesDebug() const override
Whether the effect dialog should have a Debug button; default, always false.
static void StaticOutputCallback(int c, void *userdata)
bool TransferDataFromEffectWindow()
void OnFileButton(wxCommandEvent &evt)
bool TransferDataToPromptWindow()
wxString ToTimeFormat(double t)
EffectType GetType() const override
Type determines how it behaves.
bool validatePath(wxString path)
bool TransferDataToEffectWindow()
TranslatableString mAuthor
int ShowHostInterface(wxWindow &parent, const EffectDialogFactory &factory, std::shared_ptr< EffectInstance > &pInstance, EffectSettingsAccess &access, bool forceModal=false) override
Usually applies factory to self and given access.
FileNames::FileTypes ParseFileTypes(const wxString &text)
std::unique_ptr< float[]> Buffer
WaveTrack * mOutputTrack[2]
unsigned mNumSelectedChannels
EffectType GetClassification() const override
Determines which menu it appears in; default same as GetType().
static FilePaths GetNyquistSearchPath()
static int StaticPutCallback(float *buffer, int channel, int64_t start, int64_t len, int64_t totlen, void *userdata)
int PutCallback(float *buffer, int channel, int64_t start, int64_t len, int64_t totlen)
wxFileName mFileName
Name of the Nyquist script file this effect is loaded from.
bool TransferDataToWindow(const EffectSettings &settings) override
Update controls for the settings.
void OnSlider(wxCommandEvent &evt)
void OnSave(wxCommandEvent &evt)
TranslatableString mName
Name of the Effect (untranslated)
wxString EscapeString(const wxString &inStr)
TranslatableString mAction
FilePath HelpPage() const override
Fully qualified local help file name, default is empty.
std::vector< NyqControl > mControls
static wxString NyquistToWxString(const char *nyqString)
void SetCommand(const wxString &cmd)
ComponentInterfaceSymbol GetSymbol() const override
FileNames::FileType ParseFileType(const wxString &text)
bool IsInteractive() const override
Whether the effect needs a dialog for entry of settings.
void BuildPromptWindow(ShuttleGui &S)
void OnTime(wxCommandEvent &evt)
PluginPath GetPath() const override
wxArrayString mCategories
static std::vector< EnumValueSymbol > ParseChoice(const wxString &text)
TranslatableString mReleaseVersion
bool VisitSettings(SettingsVisitor &visitor, EffectSettings &settings) override
bool LoadSettings(const CommandParameters &parms, EffectSettings &settings) const override
Restore settings from keys and values.
static wxString UnQuote(const wxString &s, bool allowParens=true, wxString *pExtraString=nullptr)
TranslatableString mInitError
static void resolveFilePath(wxString &path, FileExtension extension={})
void OnChoice(wxCommandEvent &evt)
static int StaticGetCallback(float *buffer, int channel, int64_t start, int64_t len, int64_t totlen, void *userdata)
sampleCount mCurBufferStart[2]
void OnText(wxCommandEvent &evt)
VendorSymbol GetVendor() const override
wxString GetVersion() const override
Dialog used with NyquistEffect.
void OnOk(wxCommandEvent &event)
static ProjectRate & Get(AudacityProject &project)
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
Retrieve samples from a track in floating-point format, regardless of the storage format.
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Defines a selected portion of a project.
Visitor of effect or command parameters. This is a base class with lots of virtual functions that do ...
virtual void Define(Arg< bool > var, const wxChar *key, bool vdefault, bool vmin=false, bool vmax=false, bool vscl=false)
virtual void DefineEnum(Arg< int > var, const wxChar *key, int vdefault, const EnumValueSymbol strings[], size_t nStrings)
SettingsVisitor that gets parameter values into a string.
SettingsVisitor that retrieves a JSON format definition of a command's parameters.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
SettingsVisitor that sets parameters to a value (from a string)
bool SpectralSelectionEnabled() const
std::shared_ptr< EffectInstance > MakeInstance() const override
Make an object maintaining short-term state of an Effect.
static bool IsSyncLockSelected(const Track *pTrack)
static TrackIterRange< Track > Group(Track *pTrack)
A kind of Track used to 'warp time'.
Abstract base class for an object holding data associated with points on a time axis.
virtual double GetStartTime() const =0
R TypeSwitch(const Functions &...functions)
Use this function rather than testing track type explicitly and making down-casts.
virtual double GetEndTime() const =0
auto Leaders() -> TrackIterRange< TrackType >
static TrackList & Get(AudacityProject &project)
auto Selected() -> TrackIterRange< TrackType >
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
TranslatableString & Format(Args &&...args) &
Capture variadic format arguments (by copy) when there is no plural.
NotifyingSelectedRegion selectedRegion
static ViewInfo & Get(AudacityProject &project)
A Track that contains audio waveform data.
bool Append(constSamplePtr buffer, sampleFormat format, size_t len, unsigned int stride=1, sampleFormat effectiveFormat=widestSampleFormat) override
size_t GetBestBlockSize(sampleCount t) const override
This returns a nonnegative number of samples meant to size a memory buffer.
WaveClipPointers SortedClipArray()
const SpectrogramSettings & GetSpectrogramSettings() const
std::pair< float, float > GetMinMax(double t0, double t1, bool mayThrow=true) const
size_t GetIdealBlockSize()
float GetRMS(double t0, double t1, bool mayThrow=true) const
double GetEndTime() const override
Get the time at which the last clip in the track ends, plus recorded stuff.
double GetRate() const override
void ClearAndPaste(double t0, double t1, const Track *src, bool preserve=true, bool merge=true, const TimeWarper *effectWarper=NULL)
Holder EmptyCopy(const SampleBlockFactoryPtr &pFactory={}, bool keepLink=true) const
static WaveTrackView * Find(WaveTrack *pTrack)
Positions or offsets within audio files need a wide type.
long long as_long_long() const
Extend wxArrayString with move operations and construction and insertion fromstd::initializer_list.
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
void Yield()
Dispatch waiting events, including actions enqueued by CallAfter.
FILES_API FilePath PlugInDir()
The user plug-in directory (not a system one)
FILES_API FilePath HtmlHelpDir()
FILES_API wxFileNameWrapper DefaultToDocumentsFolder(const wxString &preference)
FILES_API void AddUniquePathToPathList(const FilePath &path, FilePaths &pathList)
FILES_API FilePath BaseDir()
FILES_API FilePath DataDir()
Audacity user data directory.
FILES_API FilePath FindDefaultPath(Operation op)
FILES_API const FilePaths & AudacityPathList()
A list of directories that should be searched for Audacity files (plug-ins, help files,...
wxString GetSystemLanguageCode(const FilePaths &pathList)
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
FILES_API wxString TempDir()
static RegisteredToolbarFactory factory
Externalized state of a plug-in.
"finally" as in The C++ Programming Language, 4th ed., p. 358 Useful for defining ad-hoc RAII actions...
Options & MenuEnabled(bool enable)
Options & AutoPos(bool enable)
Options & ReadOnly(bool enable)
bool Tokenize(const wxString &line, bool eof, size_t trimStart, size_t trimEnd)