Skip to content

Commit

Permalink
Add a Tuning Visualizer for MTS-ESP Mode (#7162)
Browse files Browse the repository at this point in the history
In MTS-ESP mode you can use a subset of the tuning editor
so rename it tuning visualizer in that mode and show the true
keys and the keyboard display

Closes #7146
  • Loading branch information
baconpaul authored Aug 10, 2023
1 parent 6bc34f7 commit 5e46644
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 10 deletions.
16 changes: 16 additions & 0 deletions src/surge-xt/gui/SurgeGUIEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,15 @@ void SurgeGUIEditor::idle()

scanJuceSkinComponents = false;
}

if (synth->storage.oddsound_mts_active_as_client)
{
auto w = getOverlayWrapperIfOpen(TUNING_EDITOR);
if (w && (slowIdleCounter % 30 == 0))
{
w->repaint();
}
}
}

void SurgeGUIEditor::toggle_mod_editing()
Expand Down Expand Up @@ -3374,6 +3383,13 @@ juce::PopupMenu SurgeGUIEditor::makeTuningMenu(const juce::Point<int> &where, bo
tuningSubMenu.addItem(Surge::GUI::toOSCase("Current Tuning: ") + mtsScale, false, false,
[]() {});

std::string openname = isAnyOverlayPresent(TUNING_EDITOR) ? "Close " : "Open ";

Surge::GUI::addMenuWithShortcut(tuningSubMenu,
Surge::GUI::toOSCase(openname + "Tuning Visualizer..."),
showShortcutDescription("Alt + T", u8"\U00002325T"),
[this]() { this->toggleOverlay(TUNING_EDITOR); });

tuningSubMenu.addSeparator();
}
#endif
Expand Down
97 changes: 87 additions & 10 deletions src/surge-xt/gui/overlays/TuningOverlays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <chrono>
#include "juce_gui_extra/juce_gui_extra.h"
#include "UnitConversions.h"
#include "libMTSClient.h"

namespace Surge
{
Expand All @@ -44,6 +45,14 @@ class TuningTableListBoxModel : public juce::TableListBoxModel,
TuningTableListBoxModel() {}
~TuningTableListBoxModel() { table = nullptr; }

SurgeStorage *storage{nullptr};
void setStorage(SurgeStorage *s)
{
storage = s;
if (table)
table->repaint();
}

void setTableListBox(juce::TableListBox *t) { table = t; }

void setupDefaultHeaders(juce::TableListBox *table)
Expand Down Expand Up @@ -172,7 +181,16 @@ class TuningTableListBoxModel : public juce::TableListBoxModel,
}

auto mn = rowNumber;
double fr = tuning.frequencyForMidiNote(mn);
double fr = 0;

if (storage && storage->oddsound_mts_client && storage->oddsound_mts_active_as_client)
{
fr = MTS_NoteToFrequency(storage->oddsound_mts_client, rowNumber, 0);
}
else
{
fr = tuning.frequencyForMidiNote(mn);
}

std::string notenum, notename, display;

Expand Down Expand Up @@ -1434,6 +1452,33 @@ struct IntervalMatrix : public juce::Component, public Surge::GUI::SkinConsuming

ypos += rowHeight;

auto noteToFreq = [this](auto note) -> float {
auto st = matrix->overlay->storage;
auto mts = matrix->overlay->mtsMode;
if (mts)
{
return MTS_NoteToFrequency(st->oddsound_mts_client, note, 0);
}
else
{
return matrix->tuning.frequencyForMidiNote(note);
}
};

auto noteToPitch = [this](auto note) -> float {
auto st = matrix->overlay->storage;
auto mts = matrix->overlay->mtsMode;
if (mts)
{
return log2(MTS_NoteToFrequency(st->oddsound_mts_client, note, 0) /
Tunings::MIDI_0_FREQ);
}
else
{
return matrix->tuning.logScaledFrequencyForMidiNote(note);
}
};

for (int i = 0; i < bs.size(); ++i)
{
if (bs[i])
Expand All @@ -1443,11 +1488,11 @@ struct IntervalMatrix : public juce::Component, public Surge::GUI::SkinConsuming
g.drawText(get_notename(i, oct_offset), hpos, ypos, colWidth, rowHeight,
juce::Justification::centredLeft);
hpos += colWidth;
g.drawText(fmt::format("{:.2f}Hz", matrix->tuning.frequencyForMidiNote(i)),
hpos, ypos, colWidth, rowHeight, juce::Justification::centredLeft);
g.drawText(fmt::format("{:.2f}Hz", noteToFreq(i)), hpos, ypos, colWidth,
rowHeight, juce::Justification::centredLeft);
hpos += colWidth;

auto pitch0 = matrix->tuning.logScaledFrequencyForMidiNote(i);
auto pitch0 = noteToPitch(i);

for (int j = 0; j < bs.size(); ++j)
{
Expand All @@ -1461,7 +1506,7 @@ struct IntervalMatrix : public juce::Component, public Surge::GUI::SkinConsuming
g.setColour(juce::Colours::darkgrey);
g.drawRect(bx, 1);
g.setColour(skin->getColor(clr::IntervalText));
auto pitch = matrix->tuning.logScaledFrequencyForMidiNote(j);
auto pitch = noteToPitch(j);
g.drawText(fmt::format("{:.2f}", 1200 * (pitch0 - pitch)), bx,
juce::Justification::centred);
}
Expand Down Expand Up @@ -2716,6 +2761,10 @@ void TuningOverlay::setStorage(SurgeStorage *s)
{
storage = s;
radialScaleGraph->setStorage(s);
tuningKeyboardTableModel->setStorage(s);
bool isOddsoundOnAsClient =
storage->oddsound_mts_active_as_client && storage->oddsound_mts_client;
setMTSMode(isOddsoundOnAsClient);
}

TuningOverlay::~TuningOverlay() = default;
Expand All @@ -2729,6 +2778,9 @@ void TuningOverlay::resized()
int kbWidth = 87;
int ctrlHeight = 35;

if (mtsMode)
ctrlHeight = 0;

t.transformPoint(w, h);

tuningKeyboardTable->setBounds(0, 0, kbWidth, h);
Expand All @@ -2755,10 +2807,13 @@ void TuningOverlay::resized()
void TuningOverlay::showEditor(int which)
{
jassert(which >= 0 && which <= 5);
if (which == 0)
controlArea->applyS->setVisible(true);
else
controlArea->applyS->setVisible(false);
if (controlArea->applyS)
{
if (which == 0)
controlArea->applyS->setVisible(true);
else
controlArea->applyS->setVisible(false);
}
sclKbmDisplay->setVisible(which == 0);
radialScaleGraph->setVisible(which == 1);
intervalMatrix->setVisible(which >= 2);
Expand Down Expand Up @@ -2936,7 +2991,14 @@ void TuningOverlay::setTuning(const Tunings::Tuning &t)

void TuningOverlay::resetParentTitle()
{
setEnclosingParentTitle("Tuning Editor - " + tuning.scale.description);
if (mtsMode)
{
setEnclosingParentTitle("Tuning Visualizer");
}
else
{
setEnclosingParentTitle("Tuning Editor - " + tuning.scale.description);
}
if (getParentComponent())
getParentComponent()->repaint();
}
Expand Down Expand Up @@ -2972,5 +3034,20 @@ void TuningOverlay::filesDropped(const juce::StringArray &files, int x, int y)
editor->juceEditor->filesDropped(files, x, y);
}

void TuningOverlay::setMTSMode(bool isMTSOn)
{
mtsMode = isMTSOn;

resetParentTitle();
resized();

if (controlArea)
controlArea->setVisible(!isMTSOn);
if (isMTSOn)
{
showEditor(5);
}
}

} // namespace Overlays
} // namespace Surge
3 changes: 3 additions & 0 deletions src/surge-xt/gui/overlays/TuningOverlays.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ struct TuningOverlay : public OverlayComponent,
Tunings::Tuning tuning;
SurgeStorage *storage{nullptr};

bool mtsMode{false};
void setMTSMode(bool isMTSOn);

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TuningOverlay);
};
} // namespace Overlays
Expand Down

0 comments on commit 5e46644

Please sign in to comment.