diff --git a/src/common/SurgeStorage.cpp b/src/common/SurgeStorage.cpp index 5f6fbc6a432..4fa8e8efbd9 100644 --- a/src/common/SurgeStorage.cpp +++ b/src/common/SurgeStorage.cpp @@ -1093,6 +1093,7 @@ double shafted_tanh(double x) void SurgeStorage::init_tables() { + isStandardTuning = true; float db60 = powf(10.f, 0.05f * -60.f); for (int i = 0; i < 512; i++) { @@ -1233,6 +1234,9 @@ float envelope_rate_linear(float x) void SurgeStorage::retuneToScale(const Surge::Storage::Scale& s) { + currentScale = s; + isStandardTuning = false; + float pitches[512]; int pos0 = 256 + scaleConstantNote(); float pitchMod = log(scaleConstantPitch())/log(2) - 1; diff --git a/src/common/SurgeStorage.h b/src/common/SurgeStorage.h index 1db84788f73..81a77a7ada5 100644 --- a/src/common/SurgeStorage.h +++ b/src/common/SurgeStorage.h @@ -561,6 +561,9 @@ class alignas(16) SurgeStorage void retuneToScale(const Surge::Storage::Scale& s); inline int scaleConstantNote() { return 48; } inline float scaleConstantPitch() { return 16.0; } + + Surge::Storage::Scale currentScale; + bool isStandardTuning; private: TiXmlDocument snapshotloader; diff --git a/src/common/Tunings.cpp b/src/common/Tunings.cpp index 73941fd0539..9a6dc24059a 100644 --- a/src/common/Tunings.cpp +++ b/src/common/Tunings.cpp @@ -5,6 +5,7 @@ #include #include #include +#include /* From: http://huygens-fokker.org/scala/scl_format.html @@ -45,8 +46,10 @@ Surge::Storage::Scale Surge::Storage::readSCLFile(std::string fname) Scale res; res.name = fname; + std::ostringstream rawOSS; while (std::getline(inf, line)) { + rawOSS << line << "\n"; if (line[0] == '!') { continue; @@ -96,6 +99,7 @@ Surge::Storage::Scale Surge::Storage::readSCLFile(std::string fname) } } + res.rawText = rawOSS.str(); return res; } @@ -118,3 +122,93 @@ std::ostream& Surge::Storage::operator<<(std::ostream& os, const Surge::Storage: os << " - " << t << "\n"; return os; } + +std::string Surge::Storage::Scale::toHtml() +{ + std::ostringstream htmls; + + htmls << + R"HTML( + + + + + + +
+
+ Surge Tuning +
+
+ )HTML" + << description << + R"HTML( +
+
+ +
+
+ Tuning Information +
+ +
+
+ )HTML" << count << " tones" << +R"HTML( +
+ + + + + + + + )HTML"; + + int ct = 2; + for( auto & t : tones ) + { + htmls << "\n"; + }; + + htmls << R"HTML( +
#DatumCentsFloat
1101
" << ct++ << ""; + if (t.type == Tone::kToneCents) + htmls << t.cents; + else + htmls << t.ratio_n << " / " << t.ratio_d; + + htmls << "" << t.cents << "" << t.floatValue << "
+
+ +
+ +
+
+ Raw File: + )HTML" << name << "
\n
\n" << rawText << R"HTML(
+      
+
+ + + )HTML"; + + return htmls.str(); + +} diff --git a/src/common/Tunings.h b/src/common/Tunings.h index 817ab9c9a1c..4360d3cb1d0 100644 --- a/src/common/Tunings.h +++ b/src/common/Tunings.h @@ -30,12 +30,15 @@ struct Scale { std::string name; std::string description; + std::string rawText; int count; std::vector tones; - Scale() : name("empty scale"), description(""), count(0) + Scale() : name("empty scale"), description(""), rawText(""), count(0) { } + + std::string toHtml(); }; std::ostream& operator<<(std::ostream& os, const Tone& sc); diff --git a/src/common/UserInteractions.h b/src/common/UserInteractions.h index 62795e53a61..6987915d398 100644 --- a/src/common/UserInteractions.h +++ b/src/common/UserInteractions.h @@ -44,6 +44,7 @@ MessageResult promptOKCancel(const std::string &message, const std::string &titl // Open a URL in a user-appropriate fashion void openURL(const std::string &url); +void showHTML(const std::string &html); // Open a folder in the system appropriate file browser (finder on macOS, explorer on win, // etc) diff --git a/src/common/gui/SurgeGUIEditor.cpp b/src/common/gui/SurgeGUIEditor.cpp index d21eb4c2603..d8b2cc09c5d 100644 --- a/src/common/gui/SurgeGUIEditor.cpp +++ b/src/common/gui/SurgeGUIEditor.cpp @@ -2806,12 +2806,13 @@ void SurgeGUIEditor::showSettingsMenu(CRect &menuRect) VSTGUI::COptionMenu::kNoDrawStyle | VSTGUI::COptionMenu::kMultipleCheckStyle); - addCallbackMenu(tuningSubMenu, "Set to Standard Tuning", + auto *st = addCallbackMenu(tuningSubMenu, "Set to Standard Tuning", [this]() { this->synth->storage.init_tables(); } ); + st->setEnabled(! this->synth->storage.isStandardTuning); tid++; addCallbackMenu(tuningSubMenu, "Apply .scl file tuning", @@ -2838,6 +2839,17 @@ void SurgeGUIEditor::showSettingsMenu(CRect &menuRect) } ); tid++; + + auto *sct = addCallbackMenu(tuningSubMenu, "Show current tuning", + [this]() + { + // Surge::UserInteractions::promptOKCancel( "Surge tuning is NONstandard tuning", "Tuning Info" ); + Surge::UserInteractions::showHTML( this->synth->storage.currentScale.toHtml() ); + } + ); + sct->setEnabled(! this->synth->storage.isStandardTuning ); + + /* tuningSubMenu->addSeparator(tid++); addCallbackMenu(tuningSubMenu, "Apply .kbm file mapping", @@ -2848,8 +2860,9 @@ void SurgeGUIEditor::showSettingsMenu(CRect &menuRect) this); } ); + */ - settingsMenu->addEntry(tuningSubMenu, "Tunings (experimental)"); + settingsMenu->addEntry(tuningSubMenu, "Tuning" ); eid++; tuningSubMenu->forget(); diff --git a/src/headless/UserInteractionsHeadless.cpp b/src/headless/UserInteractionsHeadless.cpp index 11b0422061a..99a5d695247 100644 --- a/src/headless/UserInteractionsHeadless.cpp +++ b/src/headless/UserInteractionsHeadless.cpp @@ -33,6 +33,10 @@ MessageResult promptOKCancel(const std::string &message, const std::string &titl void openURL(const std::string &url) { } +void showHTML( const std::string &html) +{ + std::cerr << "SURGE HTML: " << html << std::endl; +} void promptFileOpenDialog(const std::string& initialDirectory, const std::string& filterSuffix, diff --git a/src/linux/UserInteractionsLinux.cpp b/src/linux/UserInteractionsLinux.cpp index 2454db27642..cd0ac6e9f7a 100644 --- a/src/linux/UserInteractionsLinux.cpp +++ b/src/linux/UserInteractionsLinux.cpp @@ -66,6 +66,22 @@ void openURL(const std::string &url) } } +void showHTML( const std::string &html ) +{ + // FIXME - there's proper APIs for this that crash on MacOS + std::ostringstream fns; + fns << "/tmp/surge-tuning." << rand() << ".html"; + + FILE *f = fopen(fns.str().c_str(), "w" ); + if( f ) + { + fprintf( f, "%s", html.c_str()); + fclose(f); + std::string url = std::string("file://") + fns.str(); + openURL(url); + } +} + void openFolderInFileBrowser(const std::string& folder) { std::string url = "file://" + folder; diff --git a/src/mac/UserInteractionsMac.mm b/src/mac/UserInteractionsMac.mm index 648c6d61136..27a0549d789 100644 --- a/src/mac/UserInteractionsMac.mm +++ b/src/mac/UserInteractionsMac.mm @@ -4,6 +4,10 @@ #include #include +#include +#include +#include + namespace Surge { @@ -70,6 +74,22 @@ void openURL(const std::string& url_str) CFRelease(url); } +void showHTML( const std::string &html ) +{ + // Why does mktemp crash on macos I wonder? + std::ostringstream fns; + fns << "/var/tmp/surge-tuning." << rand() << ".html"; + + FILE *f = fopen(fns.str().c_str(), "w" ); + if( f ) + { + fprintf( f, "%s", html.c_str()); + fclose(f); + std::string url = std::string("file://") + fns.str(); + openURL(url); + } +} + void openFolderInFileBrowser(const std::string& folder) { std::string url = "file://" + folder; diff --git a/src/windows/UserInteractionsWin.cpp b/src/windows/UserInteractionsWin.cpp index 6572be52166..58264e2cf9f 100644 --- a/src/windows/UserInteractionsWin.cpp +++ b/src/windows/UserInteractionsWin.cpp @@ -45,6 +45,24 @@ void openURL(const std::string &url) ShellExecute(NULL, "open", url.c_str(), NULL, NULL, SW_SHOWNORMAL); } +void showHTML( const std::string &html ) +{ + TCHAR lpTempPathBuffer[MAX_PATH]; + + auto dwRetVal = GetTempPath(MAX_PATH, lpTempPathBuffer); + std::ostringstream fns; + fns << lpTempPathBuffer << "surge-tuning." << rand() << ".html"; + + FILE *f = fopen(fns.str().c_str(), "w" ); + if( f ) + { + fprintf( f, "%s", html.c_str()); + fclose(f); + std::string url = std::string("file:///") + fns.str(); + openURL(url); + } +} + void openFolderInFileBrowser(const std::string& folder) { std::string url = "file://" + folder;