Compare commits
2 Commits
6f2fd49107
...
0eb6325e2e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0eb6325e2e | ||
|
|
da00962842 |
@ -605,10 +605,7 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
|||||||
auto hoverFactor = isHovered ? 1.05f : 1.0f;
|
auto hoverFactor = isHovered ? 1.05f : 1.0f;
|
||||||
|
|
||||||
auto iconBounds = juce::Rectangle<float>(iconSize * hoverFactor, iconSize * hoverFactor)
|
auto iconBounds = juce::Rectangle<float>(iconSize * hoverFactor, iconSize * hoverFactor)
|
||||||
.withCentre(bounds.getCentre())
|
.withCentre(bounds.getCentre());
|
||||||
.withX(bounds.getX());
|
|
||||||
// ganz links im Button starten
|
|
||||||
;
|
|
||||||
|
|
||||||
float bypassOpacity = 1.0f;
|
float bypassOpacity = 1.0f;
|
||||||
|
|
||||||
@ -755,10 +752,6 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
|||||||
juce::RectanglePlacement::centred, bypassOpacity);
|
juce::RectanglePlacement::centred, bypassOpacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,6 +873,10 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
|||||||
juce::Slider::SliderLayout getSliderLayout (juce::Slider& slider) override
|
juce::Slider::SliderLayout getSliderLayout (juce::Slider& slider) override
|
||||||
{
|
{
|
||||||
juce::Slider::SliderLayout layout;
|
juce::Slider::SliderLayout layout;
|
||||||
|
if (slider.getName() == "LowBand Slope" || slider.getName() == "HighBand Slope") {
|
||||||
|
layout.textBoxBounds = {};
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
auto r = slider.getLocalBounds();
|
auto r = slider.getLocalBounds();
|
||||||
|
|
||||||
@ -1025,6 +1022,7 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
|||||||
class SlopeSliderLookAndFeel : public BaseSliderLookAndFeel {
|
class SlopeSliderLookAndFeel : public BaseSliderLookAndFeel {
|
||||||
public:
|
public:
|
||||||
static constexpr float labelPadding = 20.0f;
|
static constexpr float labelPadding = 20.0f;
|
||||||
|
|
||||||
juce::Slider::SliderLayout getSliderLayout(juce::Slider& slider) override
|
juce::Slider::SliderLayout getSliderLayout(juce::Slider& slider) override
|
||||||
{
|
{
|
||||||
juce::Slider::SliderLayout layout;
|
juce::Slider::SliderLayout layout;
|
||||||
@ -1136,20 +1134,25 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
|||||||
float hoverFactor = 1.0f;
|
float hoverFactor = 1.0f;
|
||||||
auto surfaceCol = Colours::SURFACECOLOUR;
|
auto surfaceCol = Colours::SURFACECOLOUR;
|
||||||
auto accentCol = Colours::ACCENTCOLOUR;
|
auto accentCol = Colours::ACCENTCOLOUR;
|
||||||
|
auto ringCol = Colours::SURFACEHOVER;
|
||||||
if (isEnabled) {
|
if (isEnabled) {
|
||||||
surfaceCol = isHovered ? Colours::SURFACEBYPASS : Colours::SURFACECOLOUR;
|
surfaceCol = isHovered ? Colours::SURFACEHOVER : Colours::SURFACECOLOUR;
|
||||||
accentCol = isHovered ? Colours::ACCENTHOVER : Colours::ACCENTCOLOUR;
|
accentCol = isHovered ? Colours::ACCENTHOVER : Colours::ACCENTCOLOUR;
|
||||||
|
ringCol = isHovered ? Colours::SURFACECOLOUR : Colours::SURFACEHOVER;
|
||||||
hoverFactor = isHovered ? 1.05f : 1.0f;
|
hoverFactor = isHovered ? 1.05f : 1.0f;
|
||||||
} else {
|
} else {
|
||||||
surfaceCol = Colours::SURFACEBYPASS;
|
surfaceCol = Colours::SURFACEBYPASS;
|
||||||
accentCol = Colours::ACCENTWEAKCOLOUR;
|
accentCol = Colours::ACCENTWEAKCOLOUR;
|
||||||
|
ringCol = Colours::SURFACEHOVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Einfacher Ring
|
// Einfacher Ring
|
||||||
g.setColour(surfaceCol);
|
g.setColour(surfaceCol);
|
||||||
g.fillEllipse(centreX - radius, centreY - radius, radius * 2.0f , radius * 2.0f);
|
g.fillEllipse(centreX - radius, centreY - radius, radius * 2.0f , radius * 2.0f);
|
||||||
//g.drawEllipse(centreX - radius, centreY - radius, radius * 2.0f, radius * 2.0f, 2.0f);
|
|
||||||
|
g.setColour(ringCol);
|
||||||
|
g.drawEllipse(centreX - radius, centreY - radius, radius * 2.0f, radius * 2.0f, arcPathWidth);
|
||||||
|
|
||||||
juce::Path valueArc;
|
juce::Path valueArc;
|
||||||
valueArc.addCentredArc(centreX, centreY, radius, radius,
|
valueArc.addCentredArc(centreX, centreY, radius, radius,
|
||||||
@ -1183,7 +1186,7 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
|||||||
case SizeMode::Freq: return 0.8f;
|
case SizeMode::Freq: return 0.8f;
|
||||||
case SizeMode::Q: return 0.8f;
|
case SizeMode::Q: return 0.8f;
|
||||||
case SizeMode::Slope: return 0.7f;
|
case SizeMode::Slope: return 0.7f;
|
||||||
case SizeMode::Global: return 1.0f;
|
case SizeMode::Global: return 0.8f;
|
||||||
case SizeMode::Mix: return 0.8f;
|
case SizeMode::Mix: return 0.8f;
|
||||||
default: return 1.0f;
|
default: return 1.0f;
|
||||||
}
|
}
|
||||||
@ -1336,6 +1339,118 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PresetMenu : public juce::Component {
|
||||||
|
public:
|
||||||
|
PresetMenu(juce::TextEditor* inputField,
|
||||||
|
juce::TextButton* saveButton,
|
||||||
|
juce::TextButton* deleteButton) {
|
||||||
|
addAndMakeVisible(*inputField);
|
||||||
|
addAndMakeVisible(*saveButton);
|
||||||
|
addAndMakeVisible(*deleteButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
class PresetMenuLookAndFeel : public juce::LookAndFeel_V4 {
|
||||||
|
public:
|
||||||
|
void drawCallOutBoxBackground(juce::CallOutBox &callOutBox, juce::Graphics &g, const juce::Path &path, juce::Image &image) override {
|
||||||
|
g.setColour(Colours::SURFACECOLOUR);
|
||||||
|
g.fillPath(path);
|
||||||
|
|
||||||
|
g.setColour (Colours::FOREGROUNDCOLOUR.withAlpha(0.3f));
|
||||||
|
g.strokePath (path, juce::PathStrokeType (1.0f));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int getCallOutBoxBorderSize (const juce::CallOutBox&) override
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PresetButtonsLookAndFeel : public juce::LookAndFeel_V4 {
|
||||||
|
public:
|
||||||
|
|
||||||
|
void drawButtonText(juce::Graphics &g, juce::TextButton &button, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override {
|
||||||
|
auto bounds = button.getLocalBounds();
|
||||||
|
|
||||||
|
// Text holen
|
||||||
|
auto text = button.getButtonText();
|
||||||
|
|
||||||
|
// Farbe wählen
|
||||||
|
auto isHovered = button.isMouseOver();
|
||||||
|
bool isEnabled = button.isEnabled();
|
||||||
|
juce::Colour colour = isHovered ? Colours::FOREGROUNDHOVER : Colours::FOREGROUNDCOLOUR;
|
||||||
|
|
||||||
|
if (!isEnabled) colour = colour.withMultipliedAlpha(0.6f);
|
||||||
|
|
||||||
|
|
||||||
|
g.setColour(colour);
|
||||||
|
|
||||||
|
// Font einstellen
|
||||||
|
auto font = Typography::getFont(Typography::Style::Button, 1.0f);
|
||||||
|
g.setFont(font);
|
||||||
|
|
||||||
|
// Text zeichnen
|
||||||
|
g.drawFittedText(text,
|
||||||
|
bounds.reduced(4),
|
||||||
|
juce::Justification::centred,
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
void drawButtonBackground(juce::Graphics& g, juce::Button& button,
|
||||||
|
const juce::Colour& backgroundColour,
|
||||||
|
bool shouldDrawButtonAsHighlighted,
|
||||||
|
bool shouldDrawButtonAsDown) override
|
||||||
|
{
|
||||||
|
auto bounds = button.getLocalBounds().toFloat();
|
||||||
|
|
||||||
|
bool isHovered = button.isMouseOver();
|
||||||
|
bool isEnabled = button.isEnabled();
|
||||||
|
|
||||||
|
auto colour = isHovered ? Colours::BACKGROUNDHOVER : Colours::BACKGROUNDCOLOUR;
|
||||||
|
if (!isEnabled) colour = colour.withMultipliedAlpha(0.6f);
|
||||||
|
|
||||||
|
g.setColour(colour);
|
||||||
|
g.fillRoundedRectangle(bounds.reduced(1.0f), 4.0f);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class PresetComboBoxLookAndFeel : public juce::LookAndFeel_V4 {
|
||||||
|
public:
|
||||||
|
juce::PopupMenu::Options getOptionsForComboBoxPopupMenu(juce::ComboBox& box,
|
||||||
|
juce::Label& label) override
|
||||||
|
{
|
||||||
|
// Basis-Options holen
|
||||||
|
auto options = juce::LookAndFeel_V4::getOptionsForComboBoxPopupMenu(box, label);
|
||||||
|
|
||||||
|
// Anzahl der sichtbaren Einträge
|
||||||
|
const int visibleRows = 5;
|
||||||
|
|
||||||
|
// Höhe einer Zeile
|
||||||
|
auto font = getComboBoxFont(box);
|
||||||
|
int rowHeight = (int)std::ceil(font.getHeight() * 1.6f);
|
||||||
|
|
||||||
|
// Maximale Höhe des Popups
|
||||||
|
int maxPopupHeight = visibleRows * rowHeight;
|
||||||
|
|
||||||
|
// Screen-Bounds der ComboBox
|
||||||
|
auto boxScreen = box.getScreenBounds();
|
||||||
|
|
||||||
|
// Wichtig: Ein sehr breiter aber in der Höhe begrenzter Bereich
|
||||||
|
// JUCE wird das Popup darin zentrieren
|
||||||
|
juce::Rectangle<int> constrainedArea(
|
||||||
|
0, // X: ganze Screen-Breite
|
||||||
|
boxScreen.getBottom(), // Y: direkt unter der Box
|
||||||
|
juce::Desktop::getInstance().getDisplays()
|
||||||
|
.getPrimaryDisplay()->totalArea.getWidth(),
|
||||||
|
maxPopupHeight // Höhe: nur unsere gewünschten Zeilen
|
||||||
|
);
|
||||||
|
|
||||||
|
options = options.withTargetScreenArea(constrainedArea)
|
||||||
|
.withStandardItemHeight(rowHeight);
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -164,6 +164,7 @@
|
|||||||
<None Include="..\..\Resources\Fonts\Orbitron-Bold.ttf"/>
|
<None Include="..\..\Resources\Fonts\Orbitron-Bold.ttf"/>
|
||||||
<None Include="..\..\Resources\Fonts\Orbitron-Regular.ttf"/>
|
<None Include="..\..\Resources\Fonts\Orbitron-Regular.ttf"/>
|
||||||
<None Include="..\..\Resources\Fonts\Roboto-Regular.ttf"/>
|
<None Include="..\..\Resources\Fonts\Roboto-Regular.ttf"/>
|
||||||
|
<None Include="..\..\Resources\Icons\logo_icon.svg"/>
|
||||||
<None Include="..\..\Resources\Icons\bell_icon.svg"/>
|
<None Include="..\..\Resources\Icons\bell_icon.svg"/>
|
||||||
<None Include="..\..\Resources\Icons\high_cut_icon.svg"/>
|
<None Include="..\..\Resources\Icons\high_cut_icon.svg"/>
|
||||||
<None Include="..\..\Resources\Icons\high_shelf_icon.svg"/>
|
<None Include="..\..\Resources\Icons\high_shelf_icon.svg"/>
|
||||||
|
|||||||
@ -74,6 +74,9 @@
|
|||||||
<None Include="..\..\Resources\Fonts\Roboto-Regular.ttf">
|
<None Include="..\..\Resources\Fonts\Roboto-Regular.ttf">
|
||||||
<Filter>CrystalizerEQ\Resources\Fonts</Filter>
|
<Filter>CrystalizerEQ\Resources\Fonts</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="..\..\Resources\Icons\logo_icon.svg">
|
||||||
|
<Filter>CrystalizerEQ\Resources\Icons</Filter>
|
||||||
|
</None>
|
||||||
<None Include="..\..\Resources\Icons\bell_icon.svg">
|
<None Include="..\..\Resources\Icons\bell_icon.svg">
|
||||||
<Filter>CrystalizerEQ\Resources\Icons</Filter>
|
<Filter>CrystalizerEQ\Resources\Icons</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
file="Resources/Fonts/Roboto-Regular.ttf"/>
|
file="Resources/Fonts/Roboto-Regular.ttf"/>
|
||||||
</GROUP>
|
</GROUP>
|
||||||
<GROUP id="{3DCFA257-AECE-2625-016F-D02D71FFA24B}" name="Icons">
|
<GROUP id="{3DCFA257-AECE-2625-016F-D02D71FFA24B}" name="Icons">
|
||||||
|
<FILE id="RCNwIt" name="logo_icon.svg" compile="0" resource="1" file="Resources/Icons/logo_icon.svg"/>
|
||||||
<FILE id="waE621" name="bell_icon.svg" compile="0" resource="1" file="Resources/Icons/bell_icon.svg"/>
|
<FILE id="waE621" name="bell_icon.svg" compile="0" resource="1" file="Resources/Icons/bell_icon.svg"/>
|
||||||
<FILE id="KOfMYl" name="high_cut_icon.svg" compile="0" resource="1"
|
<FILE id="KOfMYl" name="high_cut_icon.svg" compile="0" resource="1"
|
||||||
file="Resources/Icons/high_cut_icon.svg"/>
|
file="Resources/Icons/high_cut_icon.svg"/>
|
||||||
|
|||||||
@ -11413,63 +11413,88 @@ static const unsigned char temp_binary_data_6[] =
|
|||||||
|
|
||||||
const char* RobotoRegular_ttf = (const char*) temp_binary_data_6;
|
const char* RobotoRegular_ttf = (const char*) temp_binary_data_6;
|
||||||
|
|
||||||
//================== bell_icon.svg ==================
|
//================== logo_icon.svg ==================
|
||||||
static const unsigned char temp_binary_data_7[] =
|
static const unsigned char temp_binary_data_7[] =
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
|
"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 3100 3100\">\n"
|
||||||
|
" <g id=\"Ebene_2\" data-name=\"Ebene 2\">\n"
|
||||||
|
" <circle cx=\"1550.48\" cy=\"1550\" r=\"64\" fill=\"#333\"/>\n"
|
||||||
|
" </g>\n"
|
||||||
|
" <g id=\"Ebene_3\" data-name=\"Ebene 3\">\n"
|
||||||
|
" <path d=\"M1512.64,1563.07c4.53,0,8.47-4.21,9.59-8.78.37-1.57.45-2.93.45-4.86,0-1.36,0-2.5-.3-3.71-.89-4.64-4.46-8.85-9.22-8.85-6.1,0-10.26,5.78-10.26,13.64,0,6.57,3.49,12.57,9.74,12.57ZM1523.38,1559.03c-2.38,4.14-6.65,9.03-12.38,9.03-8.55,0-14.7"
|
||||||
|
"2-6.85-14.72-17.35,0-11.28,7.73-18.78,16.06-18.78,11.02,0,11.04,9.03,11.04,9.03l1.81-9.03h7.23l-5.27,18.1,5.27,18.03h-7.23\" fill=\"#fcfaf9\"/>\n"
|
||||||
|
" <path d=\"M1604.67,1546.39c0-9.91-6.59-14.45-18.06-14.45-11.68.09-18.06,4.49-18.06,14.45,0,8.11,9.03,12.65,9.03,12.65l-9.03,1.76v7.23l13.55-3.96v-5.02c-4.11-2.29-8.85-5.06-8.85-10.84,0-7.24,4.4-9.76,13.37-9.69,9.1,0,13.37,2.53,13.37,9.69,0,5.74-4"
|
||||||
|
".73,8.53-8.85,10.84v5.04l13.55,3.95v-7.23l-9.03-1.76s9.03-4.55,9.03-12.65Z\" fill=\"#fcfaf9\"/>\n"
|
||||||
|
" <polygon points=\"1534.67 1572.58 1543.71 1550 1536.93 1527.42 1496.29 1527.42 1496.29 1522.9 1541.45 1522.9 1550.48 1540.97 1559.51 1522.9 1604.67 1522.9 1604.67 1527.42 1564.03 1527.42 1557.25 1550 1566.29 1572.58 1604.67 1572.58 1604.67 1577.1"
|
||||||
|
" 1561.77 1577.1 1550.48 1554.52 1539.19 1577.1 1496.29 1577.1 1496.29 1572.58 1534.67 1572.58\" fill=\"#56feff\"/>\n"
|
||||||
|
" </g>\n"
|
||||||
|
" <g id=\"Ebene_5\" data-name=\"Ebene 5\">\n"
|
||||||
|
" <rect x=\"1582.09\" y=\"1554.52\" width=\"9.03\" height=\"13.55\" fill=\"#333\"/>\n"
|
||||||
|
" <rect x=\"1581.53\" y=\"1565.63\" width=\"11.31\" height=\"4.42\" fill=\"#333\"/>\n"
|
||||||
|
" <rect x=\"1585.12\" y=\"1564.25\" width=\"11.31\" height=\"4.42\" transform=\"translate(1131.12 -618.28) rotate(33.56)\" fill=\"#333\"/>\n"
|
||||||
|
" <polygon points=\"1587.05 1561.29 1584.91 1557.43 1592.17 1553.63 1591.89 1558.6 1587.05 1561.29\" fill=\"#333\"/>\n"
|
||||||
|
" </g>\n"
|
||||||
|
"</svg>";
|
||||||
|
|
||||||
|
const char* logo_icon_svg = (const char*) temp_binary_data_7;
|
||||||
|
|
||||||
|
//================== bell_icon.svg ==================
|
||||||
|
static const unsigned char temp_binary_data_8[] =
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
"<svg id=\"Ebene_1\" data-name=\"Ebene 1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28 12.02\">\n"
|
"<svg id=\"Ebene_1\" data-name=\"Ebene 1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28 12.02\">\n"
|
||||||
" <path fill=\"black\" d=\"M0,8.02h4.82c.75,0,1.45-.34,1.92-.92L11.42,1.24c1.32-1.65,3.84-1.65,5.16,0l4.68,5.86c.47.58,1.17.92,1.92.92h4.82v4h-4.82c-.75,0-1.45-.34-1.92-.92l-5.73-7.16c-.79-.98-2.28-.98-3.07,0l-5.73,7.16c-.47.58-1.17.92-1.92.92H0s0-4,"
|
" <path fill=\"black\" d=\"M0,8.02h4.82c.75,0,1.45-.34,1.92-.92L11.42,1.24c1.32-1.65,3.84-1.65,5.16,0l4.68,5.86c.47.58,1.17.92,1.92.92h4.82v4h-4.82c-.75,0-1.45-.34-1.92-.92l-5.73-7.16c-.79-.98-2.28-.98-3.07,0l-5.73,7.16c-.47.58-1.17.92-1.92.92H0s0-4,"
|
||||||
"0-4Z\"/>\n"
|
"0-4Z\"/>\n"
|
||||||
"</svg>";
|
"</svg>";
|
||||||
|
|
||||||
const char* bell_icon_svg = (const char*) temp_binary_data_7;
|
const char* bell_icon_svg = (const char*) temp_binary_data_8;
|
||||||
|
|
||||||
//================== high_cut_icon.svg ==================
|
//================== high_cut_icon.svg ==================
|
||||||
static const unsigned char temp_binary_data_8[] =
|
static const unsigned char temp_binary_data_9[] =
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
"<svg id=\"Ebene_1\" data-name=\"Ebene 1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\">\n"
|
"<svg id=\"Ebene_2\" data-name=\"Ebene 2\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29.49 36.9\">\n"
|
||||||
" <path fill=\"black\" d=\"M24,23.02V4C24,1.79,22.21,0,20,0H.98C.44,0,0,.44,0,.98v2.03c0,.54.44.98.98.98h17.02c1.2,0,2,.8,2,2v17.02c0,.54.44.98.98.98h2.05c.54,0,.98-.44.98-.98Z\"/>\n"
|
" <path d=\"M4.68,17.31v-.81c0-.33.27-.59.59-.59h17.58c1.08,0,2.03.72,2.32,1.76l4.3,15.48c.11.38-.18.75-.57.75h-.78c-.26,0-.49-.17-.57-.42l-4.34-13.89c-.31-1.01-1.24-1.69-2.3-1.69H5.27c-.33,0-.59-.27-.59-.59Z\"/>\n"
|
||||||
"</svg>";
|
"</svg>";
|
||||||
|
|
||||||
const char* high_cut_icon_svg = (const char*) temp_binary_data_8;
|
const char* high_cut_icon_svg = (const char*) temp_binary_data_9;
|
||||||
|
|
||||||
//================== high_shelf_icon.svg ==================
|
//================== high_shelf_icon.svg ==================
|
||||||
static const unsigned char temp_binary_data_9[] =
|
static const unsigned char temp_binary_data_10[] =
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
"<svg id=\"Ebene_1\" data-name=\"Ebene 1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28 12\">\n"
|
"<svg id=\"Ebene_1\" data-name=\"Ebene 1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28 12\">\n"
|
||||||
" <path fill=\"black\" d=\"M11.23,6.39l5.62-4.77c1.23-1.04,2.79-1.61,4.4-1.61h6.04c.4,0,.72.32.72.72v2.56c0,.4-.32.72-.72.72h-6.08c-1.62,0-3.18.58-4.41,1.63l-5.56,4.75c-1.23,1.05-2.79,1.63-4.41,1.63H.72c-.4,0-.72-.32-.72-.72v-2.56c0-.4.32-.72.72-.72h"
|
" <path fill=\"black\" d=\"M11.23,6.39l5.62-4.77c1.23-1.04,2.79-1.61,4.4-1.61h6.04c.4,0,.72.32.72.72v2.56c0,.4-.32.72-.72.72h-6.08c-1.62,0-3.18.58-4.41,1.63l-5.56,4.75c-1.23,1.05-2.79,1.63-4.41,1.63H.72c-.4,0-.72-.32-.72-.72v-2.56c0-.4.32-.72.72-.72h"
|
||||||
"6.12c1.61,0,3.17-.57,4.4-1.61Z\"/>\n"
|
"6.12c1.61,0,3.17-.57,4.4-1.61Z\"/>\n"
|
||||||
"</svg>";
|
"</svg>";
|
||||||
|
|
||||||
const char* high_shelf_icon_svg = (const char*) temp_binary_data_9;
|
const char* high_shelf_icon_svg = (const char*) temp_binary_data_10;
|
||||||
|
|
||||||
//================== low_cut_icon.svg ==================
|
//================== low_cut_icon.svg ==================
|
||||||
static const unsigned char temp_binary_data_10[] =
|
static const unsigned char temp_binary_data_11[] =
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
"<svg id=\"Ebene_1\" data-name=\"Ebene 1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\">\n"
|
"<svg id=\"Ebene_2\" data-name=\"Ebene 2\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29.49 36.9\">\n"
|
||||||
" <path fill=\"black\" d=\"M0,23.02V4C0,1.79,1.79,0,4,0h19.02c.54,0,.98.44.98.98v2.03c0,.54-.44.98-.98.98H6c-1.2,0-2,.8-2,2v17.02c0,.54-.44.98-.98.98H.98c-.54,0-.98-.44-.98-.98Z\"/>\n"
|
" <path d=\"M29.49,17.31v-.81c0-.33-.27-.59-.59-.59H11.32c-1.08,0-2.03.72-2.32,1.76l-4.3,15.48c-.11.38.18.75.57.75h.78c.26,0,.49-.17.57-.42l4.34-13.89c.31-1.01,1.24-1.69,2.3-1.69h15.64c.33,0,.59-.27.59-.59Z\"/>\n"
|
||||||
"</svg>";
|
"</svg>";
|
||||||
|
|
||||||
const char* low_cut_icon_svg = (const char*) temp_binary_data_10;
|
const char* low_cut_icon_svg = (const char*) temp_binary_data_11;
|
||||||
|
|
||||||
//================== low_shelf_icon.svg ==================
|
//================== low_shelf_icon.svg ==================
|
||||||
static const unsigned char temp_binary_data_11[] =
|
static const unsigned char temp_binary_data_12[] =
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
"<svg id=\"Ebene_1\" data-name=\"Ebene 1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28 12\">\n"
|
"<svg id=\"Ebene_1\" data-name=\"Ebene 1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 28 12\">\n"
|
||||||
" <path fill=\"black\" d=\"M16.77,6.39L11.15,1.61C9.92.57,8.36,0,6.75,0H.72C.32,0,0,.32,0,.72v2.56c0,.4.32.72.72.72h6.08c1.62,0,3.18.58,4.41,1.63l5.56,4.75c1.23,1.05,2.79,1.63,4.41,1.63h6.11c.4,0,.72-.32.72-.72v-2.56c0-.4-.32-.72-.72-.72h-6.12c-1.61,"
|
" <path fill=\"black\" d=\"M16.77,6.39L11.15,1.61C9.92.57,8.36,0,6.75,0H.72C.32,0,0,.32,0,.72v2.56c0,.4.32.72.72.72h6.08c1.62,0,3.18.58,4.41,1.63l5.56,4.75c1.23,1.05,2.79,1.63,4.41,1.63h6.11c.4,0,.72-.32.72-.72v-2.56c0-.4-.32-.72-.72-.72h-6.12c-1.61,"
|
||||||
"0-3.17-.57-4.4-1.61Z\"/>\n"
|
"0-3.17-.57-4.4-1.61Z\"/>\n"
|
||||||
"</svg>";
|
"</svg>";
|
||||||
|
|
||||||
const char* low_shelf_icon_svg = (const char*) temp_binary_data_11;
|
const char* low_shelf_icon_svg = (const char*) temp_binary_data_12;
|
||||||
|
|
||||||
//================== preset_menu_icon.svg ==================
|
//================== preset_menu_icon.svg ==================
|
||||||
static const unsigned char temp_binary_data_12[] =
|
static const unsigned char temp_binary_data_13[] =
|
||||||
"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 30 30\" width=\"60px\" height=\"60px\"><path d=\"M 3 7 A 1.0001 1.0001 0 1 0 3 9 L 27 9 A 1.0001 1.0001 0 1 0 27 7 L 3 7 z M 3 14 A 1.0001 1.0001 0 1 0 3 16 L 27 16 A 1.0001 1.0001 0 1 0 27 14 "
|
"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 30 30\" width=\"60px\" height=\"60px\"><path d=\"M 3 7 A 1.0001 1.0001 0 1 0 3 9 L 27 9 A 1.0001 1.0001 0 1 0 27 7 L 3 7 z M 3 14 A 1.0001 1.0001 0 1 0 3 16 L 27 16 A 1.0001 1.0001 0 1 0 27 14 "
|
||||||
"L 3 14 z M 3 21 A 1.0001 1.0001 0 1 0 3 23 L 27 23 A 1.0001 1.0001 0 1 0 27 21 L 3 21 z\" fill=\"black\"/></svg>";
|
"L 3 14 z M 3 21 A 1.0001 1.0001 0 1 0 3 23 L 27 23 A 1.0001 1.0001 0 1 0 27 21 L 3 21 z\" fill=\"black\"/></svg>";
|
||||||
|
|
||||||
const char* preset_menu_icon_svg = (const char*) temp_binary_data_12;
|
const char* preset_menu_icon_svg = (const char*) temp_binary_data_13;
|
||||||
|
|
||||||
//================== crystalize_button_active_icon.svg ==================
|
//================== crystalize_button_active_icon.svg ==================
|
||||||
static const unsigned char temp_binary_data_13[] =
|
static const unsigned char temp_binary_data_14[] =
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 32\">\n"
|
"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 32\">\n"
|
||||||
" <g id=\"Ebene_6\" data-name=\"Ebene 6\">\n"
|
" <g id=\"Ebene_6\" data-name=\"Ebene 6\">\n"
|
||||||
@ -11548,10 +11573,10 @@ static const unsigned char temp_binary_data_13[] =
|
|||||||
" </g>\n"
|
" </g>\n"
|
||||||
"</svg>";
|
"</svg>";
|
||||||
|
|
||||||
const char* crystalize_button_active_icon_svg = (const char*) temp_binary_data_13;
|
const char* crystalize_button_active_icon_svg = (const char*) temp_binary_data_14;
|
||||||
|
|
||||||
//================== crystalize_button_passive_icon.svg ==================
|
//================== crystalize_button_passive_icon.svg ==================
|
||||||
static const unsigned char temp_binary_data_14[] =
|
static const unsigned char temp_binary_data_15[] =
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 32\">\n"
|
"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 32\">\n"
|
||||||
" <g id=\"Ebene_6\" data-name=\"Ebene 6\">\n"
|
" <g id=\"Ebene_6\" data-name=\"Ebene 6\">\n"
|
||||||
@ -11629,17 +11654,17 @@ static const unsigned char temp_binary_data_14[] =
|
|||||||
" </g>\n"
|
" </g>\n"
|
||||||
"</svg>";
|
"</svg>";
|
||||||
|
|
||||||
const char* crystalize_button_passive_icon_svg = (const char*) temp_binary_data_14;
|
const char* crystalize_button_passive_icon_svg = (const char*) temp_binary_data_15;
|
||||||
|
|
||||||
//================== bypass_icon.svg ==================
|
//================== bypass_icon.svg ==================
|
||||||
static const unsigned char temp_binary_data_15[] =
|
static const unsigned char temp_binary_data_16[] =
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
"<svg id=\"Ebene_1\" data-name=\"Ebene 1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 22 23\">\n"
|
"<svg id=\"Ebene_1\" data-name=\"Ebene 1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 22 23\">\n"
|
||||||
" <rect x=\"10\" width=\"2\" height=\"12\"/>\n"
|
" <rect x=\"10\" width=\"2\" height=\"12\"/>\n"
|
||||||
" <path d=\"M13,1.19v1.87c4.1.91,7.17,4.57,7.17,8.94,0,5.06-4.1,9.17-9.17,9.17S1.83,17.06,1.83,12C1.83,7.63,4.9,3.97,9,3.06v-1.87C3.88,2.13,0,6.61,0,12c0,6.08,4.92,11,11,11s11-4.92,11-11c0-5.39-3.88-9.87-9-10.81Z\" fill=\"black\"/>\n"
|
" <path d=\"M13,1.19v1.87c4.1.91,7.17,4.57,7.17,8.94,0,5.06-4.1,9.17-9.17,9.17S1.83,17.06,1.83,12C1.83,7.63,4.9,3.97,9,3.06v-1.87C3.88,2.13,0,6.61,0,12c0,6.08,4.92,11,11,11s11-4.92,11-11c0-5.39-3.88-9.87-9-10.81Z\" fill=\"black\"/>\n"
|
||||||
"</svg>";
|
"</svg>";
|
||||||
|
|
||||||
const char* bypass_icon_svg = (const char*) temp_binary_data_15;
|
const char* bypass_icon_svg = (const char*) temp_binary_data_16;
|
||||||
|
|
||||||
|
|
||||||
const char* getNamedResource (const char* resourceNameUTF8, int& numBytes);
|
const char* getNamedResource (const char* resourceNameUTF8, int& numBytes);
|
||||||
@ -11660,10 +11685,11 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes)
|
|||||||
case 0xcbceafb3: numBytes = 24668; return OrbitronBold_ttf;
|
case 0xcbceafb3: numBytes = 24668; return OrbitronBold_ttf;
|
||||||
case 0x9c8232dc: numBytes = 24716; return OrbitronRegular_ttf;
|
case 0x9c8232dc: numBytes = 24716; return OrbitronRegular_ttf;
|
||||||
case 0x93fe9a1e: numBytes = 146004; return RobotoRegular_ttf;
|
case 0x93fe9a1e: numBytes = 146004; return RobotoRegular_ttf;
|
||||||
|
case 0xa297e1b2: numBytes = 1793; return logo_icon_svg;
|
||||||
case 0x1024555a: numBytes = 397; return bell_icon_svg;
|
case 0x1024555a: numBytes = 397; return bell_icon_svg;
|
||||||
case 0x46c5a278: numBytes = 316; return high_cut_icon_svg;
|
case 0x46c5a278: numBytes = 355; return high_cut_icon_svg;
|
||||||
case 0x0133c050: numBytes = 420; return high_shelf_icon_svg;
|
case 0x0133c050: numBytes = 420; return high_shelf_icon_svg;
|
||||||
case 0x31532e06: numBytes = 317; return low_cut_icon_svg;
|
case 0x31532e06: numBytes = 353; return low_cut_icon_svg;
|
||||||
case 0x7e8ca05e: numBytes = 410; return low_shelf_icon_svg;
|
case 0x7e8ca05e: numBytes = 410; return low_shelf_icon_svg;
|
||||||
case 0x4df4bf1e: numBytes = 350; return preset_menu_icon_svg;
|
case 0x4df4bf1e: numBytes = 350; return preset_menu_icon_svg;
|
||||||
case 0xd842aaab: numBytes = 6343; return crystalize_button_active_icon_svg;
|
case 0xd842aaab: numBytes = 6343; return crystalize_button_active_icon_svg;
|
||||||
@ -11685,6 +11711,7 @@ const char* namedResourceList[] =
|
|||||||
"OrbitronBold_ttf",
|
"OrbitronBold_ttf",
|
||||||
"OrbitronRegular_ttf",
|
"OrbitronRegular_ttf",
|
||||||
"RobotoRegular_ttf",
|
"RobotoRegular_ttf",
|
||||||
|
"logo_icon_svg",
|
||||||
"bell_icon_svg",
|
"bell_icon_svg",
|
||||||
"high_cut_icon_svg",
|
"high_cut_icon_svg",
|
||||||
"high_shelf_icon_svg",
|
"high_shelf_icon_svg",
|
||||||
@ -11705,6 +11732,7 @@ const char* originalFilenames[] =
|
|||||||
"Orbitron-Bold.ttf",
|
"Orbitron-Bold.ttf",
|
||||||
"Orbitron-Regular.ttf",
|
"Orbitron-Regular.ttf",
|
||||||
"Roboto-Regular.ttf",
|
"Roboto-Regular.ttf",
|
||||||
|
"logo_icon.svg",
|
||||||
"bell_icon.svg",
|
"bell_icon.svg",
|
||||||
"high_cut_icon.svg",
|
"high_cut_icon.svg",
|
||||||
"high_shelf_icon.svg",
|
"high_shelf_icon.svg",
|
||||||
|
|||||||
@ -29,17 +29,20 @@ namespace BinaryData
|
|||||||
extern const char* RobotoRegular_ttf;
|
extern const char* RobotoRegular_ttf;
|
||||||
const int RobotoRegular_ttfSize = 146004;
|
const int RobotoRegular_ttfSize = 146004;
|
||||||
|
|
||||||
|
extern const char* logo_icon_svg;
|
||||||
|
const int logo_icon_svgSize = 1793;
|
||||||
|
|
||||||
extern const char* bell_icon_svg;
|
extern const char* bell_icon_svg;
|
||||||
const int bell_icon_svgSize = 397;
|
const int bell_icon_svgSize = 397;
|
||||||
|
|
||||||
extern const char* high_cut_icon_svg;
|
extern const char* high_cut_icon_svg;
|
||||||
const int high_cut_icon_svgSize = 316;
|
const int high_cut_icon_svgSize = 355;
|
||||||
|
|
||||||
extern const char* high_shelf_icon_svg;
|
extern const char* high_shelf_icon_svg;
|
||||||
const int high_shelf_icon_svgSize = 420;
|
const int high_shelf_icon_svgSize = 420;
|
||||||
|
|
||||||
extern const char* low_cut_icon_svg;
|
extern const char* low_cut_icon_svg;
|
||||||
const int low_cut_icon_svgSize = 317;
|
const int low_cut_icon_svgSize = 353;
|
||||||
|
|
||||||
extern const char* low_shelf_icon_svg;
|
extern const char* low_shelf_icon_svg;
|
||||||
const int low_shelf_icon_svgSize = 410;
|
const int low_shelf_icon_svgSize = 410;
|
||||||
@ -57,7 +60,7 @@ namespace BinaryData
|
|||||||
const int bypass_icon_svgSize = 406;
|
const int bypass_icon_svgSize = 406;
|
||||||
|
|
||||||
// Number of elements in the namedResourceList and originalFileNames arrays.
|
// Number of elements in the namedResourceList and originalFileNames arrays.
|
||||||
const int namedResourceListSize = 16;
|
const int namedResourceListSize = 17;
|
||||||
|
|
||||||
// Points to the start of a list of resource names.
|
// Points to the start of a list of resource names.
|
||||||
extern const char* namedResourceList[];
|
extern const char* namedResourceList[];
|
||||||
|
|||||||
@ -52,6 +52,9 @@ void CrystalizerEQAudioProcessorEditor::setupSliders() {
|
|||||||
&peak3FreqSlider, &peak3QSlider, &highBandFreqSlider, &highBandQSlider}) {
|
&peak3FreqSlider, &peak3QSlider, &highBandFreqSlider, &highBandQSlider}) {
|
||||||
s->setLookAndFeel(freqQLookAndFeel.get());
|
s->setLookAndFeel(freqQLookAndFeel.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lowBandSlopeSlider.setTextBoxStyle(juce::Slider::NoTextBox, true, 0, 0);
|
||||||
|
highBandSlopeSlider.setTextBoxStyle(juce::Slider::NoTextBox, true, 0, 0);
|
||||||
}
|
}
|
||||||
//endregion setupSliders
|
//endregion setupSliders
|
||||||
|
|
||||||
@ -130,7 +133,7 @@ void CrystalizerEQAudioProcessorEditor::setupDisplayNames() {
|
|||||||
testNoiseSlider.setTextValueSuffix(" Gain");
|
testNoiseSlider.setTextValueSuffix(" Gain");
|
||||||
|
|
||||||
//lowBandFreqSlider.setTextValueSuffix ("\nHz");
|
//lowBandFreqSlider.setTextValueSuffix ("\nHz");
|
||||||
lowBandSlopeSlider.setTextValueSuffix ("\ndB/Oct");
|
//lowBandSlopeSlider.setTextValueSuffix ("\ndB/Oct");
|
||||||
lowBandGainSlider.setTextValueSuffix("\ndB");
|
lowBandGainSlider.setTextValueSuffix("\ndB");
|
||||||
//lowBandQSlider.setTextValueSuffix ("\nQ");
|
//lowBandQSlider.setTextValueSuffix ("\nQ");
|
||||||
|
|
||||||
@ -151,7 +154,7 @@ void CrystalizerEQAudioProcessorEditor::setupDisplayNames() {
|
|||||||
|
|
||||||
|
|
||||||
//highBandFreqSlider.setTextValueSuffix ("\nHz");
|
//highBandFreqSlider.setTextValueSuffix ("\nHz");
|
||||||
highBandSlopeSlider.setTextValueSuffix ("\ndB/Oct");
|
//highBandSlopeSlider.setTextValueSuffix ("\ndB/Oct");
|
||||||
highBandGainSlider.setTextValueSuffix("\ndB");
|
highBandGainSlider.setTextValueSuffix("\ndB");
|
||||||
// highBandQSlider.setTextValueSuffix ("\nQ");
|
// highBandQSlider.setTextValueSuffix ("\nQ");
|
||||||
|
|
||||||
@ -329,17 +332,30 @@ void CrystalizerEQAudioProcessorEditor::disableHighBand(const float target) {
|
|||||||
//region disableEverything
|
//region disableEverything
|
||||||
void CrystalizerEQAudioProcessorEditor::disableEverything(const float target) {
|
void CrystalizerEQAudioProcessorEditor::disableEverything(const float target) {
|
||||||
bool isToggled = target <= 0.5f;
|
bool isToggled = target <= 0.5f;
|
||||||
|
|
||||||
for (auto* s : sliders) {
|
for (auto* s : sliders) {
|
||||||
s->setEnabled(isToggled);
|
s->setEnabled(isToggled);
|
||||||
}
|
}
|
||||||
for (auto* l : sliderLabels) {
|
for (auto* l : sliderLabels) {
|
||||||
l->setEnabled(isToggled);
|
l->setEnabled(isToggled);
|
||||||
}
|
}
|
||||||
//TODO: If band bypass is active prior to master bypass, upon reactivating master the bypassed band is getting active.
|
|
||||||
peak1BypassButton.setEnabled(isToggled);
|
for (auto*b : peakBypassButtons) {
|
||||||
peak2BypassButton.setEnabled(isToggled);
|
b->setEnabled(isToggled);
|
||||||
peak3BypassButton.setEnabled(isToggled);
|
const auto bypassTarget = b->getToggleState() ? 1.0f : 0.0f;
|
||||||
|
if (b == &peak1BypassButton && isToggled) {
|
||||||
|
disableLowMidBand(bypassTarget);
|
||||||
|
}
|
||||||
|
else if (b == &peak2BypassButton && isToggled) {
|
||||||
|
disableMidBand(bypassTarget);
|
||||||
|
}
|
||||||
|
else if (b == &peak3BypassButton && isToggled) {
|
||||||
|
disableHighMidBand(bypassTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resetButton.setEnabled(isToggled);
|
resetButton.setEnabled(isToggled);
|
||||||
|
|
||||||
crystalizeButton.setEnabled(isToggled);
|
crystalizeButton.setEnabled(isToggled);
|
||||||
lowBandModeBox.setEnabled(isToggled);
|
lowBandModeBox.setEnabled(isToggled);
|
||||||
highBandModeBox.setEnabled(isToggled);
|
highBandModeBox.setEnabled(isToggled);
|
||||||
@ -379,11 +395,7 @@ void CrystalizerEQAudioProcessorEditor::addComponentsToLayout() {
|
|||||||
presetArea.addAndMakeVisible(presetMenuButton);
|
presetArea.addAndMakeVisible(presetMenuButton);
|
||||||
|
|
||||||
headerBar.addAndMakeVisible(presetMenu);
|
headerBar.addAndMakeVisible(presetMenu);
|
||||||
presetMenu.addAndMakeVisible(presetNameInput);
|
|
||||||
presetMenu.addAndMakeVisible(savePresetButton);
|
|
||||||
presetMenu.addAndMakeVisible(deletePresetButton);
|
|
||||||
presetMenu.toFront(true);
|
|
||||||
presetMenu.setVisible(false);
|
|
||||||
|
|
||||||
|
|
||||||
addAndMakeVisible(mainPanel);
|
addAndMakeVisible(mainPanel);
|
||||||
@ -403,8 +415,8 @@ void CrystalizerEQAudioProcessorEditor::addComponentsToLayout() {
|
|||||||
lowBandModeBox.addAndMakeVisible(lowBell);
|
lowBandModeBox.addAndMakeVisible(lowBell);
|
||||||
lowBandModeBox.addAndMakeVisible(lowShelf);
|
lowBandModeBox.addAndMakeVisible(lowShelf);
|
||||||
lowFilterArea.addAndMakeVisible(lowBandModeBox);
|
lowFilterArea.addAndMakeVisible(lowBandModeBox);
|
||||||
lowBandModeButtons.add(&lowBypass, &lowCut, &lowBell, &lowShelf);
|
lowBandModeButtons.add(&lowBypass, &lowCut, &lowShelf, &lowBell);
|
||||||
lowBandBools = {false, false, false, true};
|
lowBandBools = {false, false, true, false};
|
||||||
|
|
||||||
|
|
||||||
lowFilterArea.addAndMakeVisible(lowBandSlopeLabel);
|
lowFilterArea.addAndMakeVisible(lowBandSlopeLabel);
|
||||||
@ -416,7 +428,9 @@ void CrystalizerEQAudioProcessorEditor::addComponentsToLayout() {
|
|||||||
lowBandSlopeSlider.addAndMakeVisible(low24);
|
lowBandSlopeSlider.addAndMakeVisible(low24);
|
||||||
lowBandSlopeSlider.addAndMakeVisible(low36);
|
lowBandSlopeSlider.addAndMakeVisible(low36);
|
||||||
lowBandSlopeSlider.addAndMakeVisible(low48);
|
lowBandSlopeSlider.addAndMakeVisible(low48);
|
||||||
|
|
||||||
lowFilterArea.addAndMakeVisible(lowBandSlopeSlider);
|
lowFilterArea.addAndMakeVisible(lowBandSlopeSlider);
|
||||||
|
lowFilterArea.addAndMakeVisible(lowdBOctLabel);
|
||||||
|
|
||||||
lowFilterArea.addAndMakeVisible(lowBandGainSlider);
|
lowFilterArea.addAndMakeVisible(lowBandGainSlider);
|
||||||
lowFilterArea.addAndMakeVisible(lowBandQSlider);
|
lowFilterArea.addAndMakeVisible(lowBandQSlider);
|
||||||
@ -465,8 +479,8 @@ void CrystalizerEQAudioProcessorEditor::addComponentsToLayout() {
|
|||||||
highBandModeBox.addAndMakeVisible(highBell);
|
highBandModeBox.addAndMakeVisible(highBell);
|
||||||
highBandModeBox.addAndMakeVisible(highShelf);
|
highBandModeBox.addAndMakeVisible(highShelf);
|
||||||
highFilterArea.addAndMakeVisible(highBandModeBox);
|
highFilterArea.addAndMakeVisible(highBandModeBox);
|
||||||
highBandModeButtons.add(&highBypass, &highCut, &highBell, &highShelf);
|
highBandModeButtons.add(&highBypass, &highCut, &highShelf, &highBell);
|
||||||
highBandBools = {false, false, false, true};
|
highBandBools = {false, false, true, false};
|
||||||
|
|
||||||
highFilterArea.addAndMakeVisible(highBandSlopeLabel);
|
highFilterArea.addAndMakeVisible(highBandSlopeLabel);
|
||||||
highFilterArea.addAndMakeVisible(highBandGainLabel);
|
highFilterArea.addAndMakeVisible(highBandGainLabel);
|
||||||
@ -478,6 +492,8 @@ void CrystalizerEQAudioProcessorEditor::addComponentsToLayout() {
|
|||||||
highBandSlopeSlider.addAndMakeVisible(high36);
|
highBandSlopeSlider.addAndMakeVisible(high36);
|
||||||
highBandSlopeSlider.addAndMakeVisible(high48);
|
highBandSlopeSlider.addAndMakeVisible(high48);
|
||||||
highFilterArea.addAndMakeVisible(highBandSlopeSlider);
|
highFilterArea.addAndMakeVisible(highBandSlopeSlider);
|
||||||
|
highFilterArea.addAndMakeVisible(highdBOctLabel);
|
||||||
|
|
||||||
|
|
||||||
highFilterArea.addAndMakeVisible(highBandGainSlider);
|
highFilterArea.addAndMakeVisible(highBandGainSlider);
|
||||||
highFilterArea.addAndMakeVisible(highBandQSlider);
|
highFilterArea.addAndMakeVisible(highBandQSlider);
|
||||||
@ -486,13 +502,12 @@ void CrystalizerEQAudioProcessorEditor::addComponentsToLayout() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addAndMakeVisible(footerBar);
|
|
||||||
footerBar.addAndMakeVisible(globalControlArea);
|
|
||||||
globalControlArea.addAndMakeVisible(inputLabel);
|
|
||||||
globalControlArea.addAndMakeVisible(outputLabel);
|
|
||||||
globalControlArea.addAndMakeVisible(inputSlider);
|
globalControlArea.addAndMakeVisible(inputSlider);
|
||||||
globalControlArea.addAndMakeVisible(outputSlider);
|
globalControlArea.addAndMakeVisible(outputSlider);
|
||||||
globalControlArea.addAndMakeVisible(masterBypassButton);
|
globalControlArea.addAndMakeVisible(masterBypassButton);
|
||||||
|
footerBar.addAndMakeVisible(globalControlArea);
|
||||||
|
addAndMakeVisible(footerBar);
|
||||||
}
|
}
|
||||||
//endregion addComponentsToLayout
|
//endregion addComponentsToLayout
|
||||||
|
|
||||||
@ -518,6 +533,7 @@ void CrystalizerEQAudioProcessorEditor::setupLabels() {
|
|||||||
setupLabel(low24, "24");
|
setupLabel(low24, "24");
|
||||||
setupLabel(low36, "36");
|
setupLabel(low36, "36");
|
||||||
setupLabel(low48, "48");
|
setupLabel(low48, "48");
|
||||||
|
setupLabel(lowdBOctLabel, "dB/Oct");
|
||||||
|
|
||||||
//PEAK 1
|
//PEAK 1
|
||||||
setupLabel (peak1FreqLabel,"Low-Mid\nHz");
|
setupLabel (peak1FreqLabel,"Low-Mid\nHz");
|
||||||
@ -544,6 +560,8 @@ void CrystalizerEQAudioProcessorEditor::setupLabels() {
|
|||||||
setupLabel(high24, "24");
|
setupLabel(high24, "24");
|
||||||
setupLabel(high36, "36");
|
setupLabel(high36, "36");
|
||||||
setupLabel(high48, "48");
|
setupLabel(high48, "48");
|
||||||
|
setupLabel(highdBOctLabel, "dB/Oct");
|
||||||
|
|
||||||
|
|
||||||
setupLabel(presetBoxLabel, "Presets");
|
setupLabel(presetBoxLabel, "Presets");
|
||||||
|
|
||||||
@ -557,6 +575,9 @@ void CrystalizerEQAudioProcessorEditor::setupFontsWithColours() {
|
|||||||
Typography::applyToLabel(titleLabel, Typography::Style::Display, 1.f);
|
Typography::applyToLabel(titleLabel, Typography::Style::Display, 1.f);
|
||||||
titleLabel.setColour(juce::Label::textColourId, Colours::ACCENTCOLOUR);
|
titleLabel.setColour(juce::Label::textColourId, Colours::ACCENTCOLOUR);
|
||||||
|
|
||||||
|
Typography::applyToLabel(presetBoxLabel, Typography::Style::H3, 1.f);
|
||||||
|
presetBoxLabel.setColour(juce::Label::textColourId, Colours::FOREGROUNDCOLOUR);
|
||||||
|
|
||||||
for (auto* l : sliderLabels) {
|
for (auto* l : sliderLabels) {
|
||||||
l->setColour(juce::Label::textColourId, Colours::FOREGROUNDCOLOUR);
|
l->setColour(juce::Label::textColourId, Colours::FOREGROUNDCOLOUR);
|
||||||
Typography::applyToLabel(*l, Typography::Style::Mono, 1.f);
|
Typography::applyToLabel(*l, Typography::Style::Mono, 1.f);
|
||||||
@ -595,7 +616,6 @@ void CrystalizerEQAudioProcessorEditor::handleLowBandModes() {
|
|||||||
lowBandModeButtons[j]->setToggleState(false, juce::dontSendNotification);
|
lowBandModeButtons[j]->setToggleState(false, juce::dontSendNotification);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Aktuellen aktivieren
|
// Aktuellen aktivieren
|
||||||
lowBandBools[i] = true;
|
lowBandBools[i] = true;
|
||||||
param->setValueNotifyingHost(param->convertTo0to1((float)i));
|
param->setValueNotifyingHost(param->convertTo0to1((float)i));
|
||||||
@ -649,8 +669,26 @@ void CrystalizerEQAudioProcessorEditor::handleHighBandModes() {
|
|||||||
//region setupEventListeners
|
//region setupEventListeners
|
||||||
void CrystalizerEQAudioProcessorEditor::setupEventListeners() {
|
void CrystalizerEQAudioProcessorEditor::setupEventListeners() {
|
||||||
presetMenuButton.onClick = [this]() {
|
presetMenuButton.onClick = [this]() {
|
||||||
bool menuOpened = presetMenuButton.getToggleState();
|
|
||||||
presetMenu.setVisible(menuOpened);
|
auto* menu = new DesignSystem::PresetMenu(&presetNameInput, &savePresetButton, &deletePresetButton);
|
||||||
|
const auto presetMenuBounds = presetMenu.getLocalBounds();
|
||||||
|
menu->setBounds(presetMenuBounds);
|
||||||
|
|
||||||
|
presetMenuLookAndFeel = std::make_unique<DesignSystem::PresetMenuLookAndFeel>();
|
||||||
|
|
||||||
|
juce::Rectangle<int> areaToPointTo = presetMenuButton.getScreenBounds();
|
||||||
|
|
||||||
|
auto* menuRaw = menu;
|
||||||
|
presetMenuSafePtr = menuRaw;
|
||||||
|
|
||||||
|
auto& box = juce::CallOutBox::launchAsynchronously(
|
||||||
|
std::unique_ptr<juce::Component>(menu),
|
||||||
|
areaToPointTo,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
box.setLookAndFeel(presetMenuLookAndFeel.get());
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
savePresetButton.onClick = [this]() {
|
savePresetButton.onClick = [this]() {
|
||||||
@ -705,8 +743,21 @@ void CrystalizerEQAudioProcessorEditor::setupEventListeners() {
|
|||||||
resetButton.onClick = [this]()
|
resetButton.onClick = [this]()
|
||||||
{
|
{
|
||||||
audioProcessor.resetAllParameters();
|
audioProcessor.resetAllParameters();
|
||||||
|
if (crystalizeButton.getToggleState()) {
|
||||||
|
isAnimatingCrystalize = true;
|
||||||
|
isFadingToActive = (svgToggleButtonLookAndFeel->activeIconOpacity < 1.0f);
|
||||||
|
}
|
||||||
resetAllCheckboxes();
|
resetAllCheckboxes();
|
||||||
|
for (auto* s : sliders) {
|
||||||
|
s->setEnabled(true);
|
||||||
|
}
|
||||||
|
for (auto* l : sliderLabels) {
|
||||||
|
l->setEnabled(true);
|
||||||
|
}
|
||||||
presetBox.setSelectedId(1, juce::dontSendNotification);
|
presetBox.setSelectedId(1, juce::dontSendNotification);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
handleLowBandModes();
|
handleLowBandModes();
|
||||||
@ -724,6 +775,7 @@ void CrystalizerEQAudioProcessorEditor::initPresetSystem() {
|
|||||||
presetBox.addItemList(presets, 1);
|
presetBox.addItemList(presets, 1);
|
||||||
presetBox.setSelectedId(1, juce::dontSendNotification);
|
presetBox.setSelectedId(1, juce::dontSendNotification);
|
||||||
|
|
||||||
|
|
||||||
presetMenuButton.setName("PresetMenuButton");
|
presetMenuButton.setName("PresetMenuButton");
|
||||||
presetMenuButton.setColour (juce::ToggleButton::textColourId, juce::Colours::black);
|
presetMenuButton.setColour (juce::ToggleButton::textColourId, juce::Colours::black);
|
||||||
presetMenuButton.setColour(juce::ToggleButton::tickColourId, juce::Colours::black);
|
presetMenuButton.setColour(juce::ToggleButton::tickColourId, juce::Colours::black);
|
||||||
@ -733,6 +785,14 @@ void CrystalizerEQAudioProcessorEditor::initPresetSystem() {
|
|||||||
presetNameInput.setJustification(juce::Justification::centred);
|
presetNameInput.setJustification(juce::Justification::centred);
|
||||||
presetNameInput.setColour(juce::TextEditor::backgroundColourId, juce::Colours::black);
|
presetNameInput.setColour(juce::TextEditor::backgroundColourId, juce::Colours::black);
|
||||||
presetNameInput.setColour(juce::TextEditor::textColourId, juce::Colours::white);
|
presetNameInput.setColour(juce::TextEditor::textColourId, juce::Colours::white);
|
||||||
|
|
||||||
|
presetButtonLookAndFeel = std::make_unique<DesignSystem::PresetButtonsLookAndFeel>();
|
||||||
|
presetComboBoxLookAndFeel = std::make_unique<DesignSystem::PresetComboBoxLookAndFeel>();
|
||||||
|
|
||||||
|
savePresetButton.setLookAndFeel(presetButtonLookAndFeel.get());
|
||||||
|
deletePresetButton.setLookAndFeel(presetButtonLookAndFeel.get());
|
||||||
|
resetButton.setLookAndFeel(presetButtonLookAndFeel.get());
|
||||||
|
// TODO: presetBox.setLookAndFeel(presetComboBoxLookAndFeel.get());
|
||||||
}
|
}
|
||||||
//endregion initPresetSystem
|
//endregion initPresetSystem
|
||||||
|
|
||||||
@ -754,6 +814,12 @@ CrystalizerEQAudioProcessorEditor::CrystalizerEQAudioProcessorEditor (Crystalize
|
|||||||
setupSliders();
|
setupSliders();
|
||||||
initPresetSystem();
|
initPresetSystem();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
auto logoIcon = juce::XmlDocument::parse (BinaryData::logo_icon_svg);
|
||||||
|
if (logoIcon != nullptr)
|
||||||
|
logoDrawable = juce::Drawable::createFromSVG (*logoIcon);
|
||||||
|
|
||||||
addAndMakeVisible (testNoiseButton);
|
addAndMakeVisible (testNoiseButton);
|
||||||
|
|
||||||
testNoiseButton.onClick = [this]() {
|
testNoiseButton.onClick = [this]() {
|
||||||
@ -790,6 +856,7 @@ CrystalizerEQAudioProcessorEditor::~CrystalizerEQAudioProcessorEditor() {
|
|||||||
crystalizeButton.setLookAndFeel(nullptr);
|
crystalizeButton.setLookAndFeel(nullptr);
|
||||||
presetMenuButton.setLookAndFeel(nullptr);
|
presetMenuButton.setLookAndFeel(nullptr);
|
||||||
|
|
||||||
|
|
||||||
for (auto* b : lowBandModeButtons) {
|
for (auto* b : lowBandModeButtons) {
|
||||||
b->setLookAndFeel(nullptr);
|
b->setLookAndFeel(nullptr);
|
||||||
}
|
}
|
||||||
@ -798,6 +865,37 @@ CrystalizerEQAudioProcessorEditor::~CrystalizerEQAudioProcessorEditor() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
float CrystalizerEQAudioProcessorEditor::getInterpolatedDb(float exactBin) {
|
||||||
|
int bin0 = static_cast<int>(std::floor(exactBin)) - 1;
|
||||||
|
int bin1 = static_cast<int>(std::floor(exactBin));
|
||||||
|
int bin2 = static_cast<int>(std::ceil(exactBin));
|
||||||
|
int bin3 = static_cast<int>(std::ceil(exactBin)) + 1;
|
||||||
|
|
||||||
|
const int maxBin = static_cast<int>(spectrumAnalyzer.renderValuesDb.size()) - 1;
|
||||||
|
bin0 = juce::jlimit(0, maxBin, bin0);
|
||||||
|
bin1 = juce::jlimit(0, maxBin, bin1);
|
||||||
|
bin2 = juce::jlimit(0, maxBin, bin2);
|
||||||
|
bin3 = juce::jlimit(0, maxBin, bin3);
|
||||||
|
|
||||||
|
float y0 = spectrumAnalyzer.renderValuesDb[bin0];
|
||||||
|
float y1 = spectrumAnalyzer.renderValuesDb[bin1];
|
||||||
|
float y2 = spectrumAnalyzer.renderValuesDb[bin2];
|
||||||
|
float y3 = spectrumAnalyzer.renderValuesDb[bin3];
|
||||||
|
|
||||||
|
float fraction = exactBin - bin1;
|
||||||
|
|
||||||
|
// Catmull-Rom Spline Interpolation
|
||||||
|
float a0 = -0.5f * y0 + 1.5f * y1 - 1.5f * y2 + 0.5f * y3;
|
||||||
|
float a1 = y0 - 2.5f * y1 + 2.0f * y2 - 0.5f * y3;
|
||||||
|
float a2 = -0.5f * y0 + 0.5f * y2;
|
||||||
|
float a3 = y1;
|
||||||
|
|
||||||
|
return a0 * fraction * fraction * fraction +
|
||||||
|
a1 * fraction * fraction +
|
||||||
|
a2 * fraction +
|
||||||
|
a3;
|
||||||
|
}
|
||||||
|
|
||||||
//region paintAnalyzer
|
//region paintAnalyzer
|
||||||
void CrystalizerEQAudioProcessorEditor::paintAnalyzer(juce::Graphics &g) {
|
void CrystalizerEQAudioProcessorEditor::paintAnalyzer(juce::Graphics &g) {
|
||||||
analyzerRect = getLocalArea(&analyzerArea, analyzerArea.getLocalBounds());
|
analyzerRect = getLocalArea(&analyzerArea, analyzerArea.getLocalBounds());
|
||||||
@ -806,14 +904,156 @@ void CrystalizerEQAudioProcessorEditor::paintAnalyzer(juce::Graphics &g) {
|
|||||||
|
|
||||||
auto r = analyzerRect.toFloat();
|
auto r = analyzerRect.toFloat();
|
||||||
|
|
||||||
// Hintergrund des Analyzer-Bereichs
|
// Hintergrund
|
||||||
g.setColour(juce::Colours::black);
|
g.setColour(juce::Colours::black);
|
||||||
g.fillRect(r);
|
g.fillRect(r);
|
||||||
|
|
||||||
// Rahmen (optional)
|
// Rahmen
|
||||||
g.setColour(juce::Colours::grey);
|
g.setColour(juce::Colours::grey);
|
||||||
g.drawRect(analyzerRect);
|
g.drawRect(analyzerRect);
|
||||||
|
|
||||||
|
// === Spektrum zeichnen ===
|
||||||
|
g.setColour(Colours::ACCENTCOLOUR);
|
||||||
|
|
||||||
|
const float analyzerWidth = analyzerRect.getWidth();
|
||||||
|
const float analyzerHeight = analyzerRect.getHeight();
|
||||||
|
const float analyzerBottom = analyzerRect.getBottom();
|
||||||
|
|
||||||
|
const float minDb = spectrumAnalyzer.MINDB;
|
||||||
|
const float maxDb = spectrumAnalyzer.MAXDB;
|
||||||
|
const float dbRange = maxDb - minDb; // = 96 dB
|
||||||
|
const float zeroDbY = analyzerBottom - (analyzerHeight * (0.0f - minDb) / dbRange); // Position von 0dB
|
||||||
|
|
||||||
|
const float minFreq = spectrumAnalyzer.MINFREQ; // 20 Hz
|
||||||
|
const float maxFreq = spectrumAnalyzer.MAXFREQ; // 20 kHz
|
||||||
|
|
||||||
|
float sampleRate = spectrumAnalyzer.sampleRate;
|
||||||
|
float deltaF = spectrumAnalyzer.deltaF;
|
||||||
|
|
||||||
|
// Zeichne für jede X-Position
|
||||||
|
juce::Path spectrumPath;
|
||||||
|
bool pathStarted = false;
|
||||||
|
|
||||||
|
// Erhöhe die Auflösung - zeichne mehr Punkte als Pixel
|
||||||
|
const int resolutionMultiplier = 4; // 4x mehr Punkte
|
||||||
|
const int numPoints = static_cast<int>(analyzerWidth) * resolutionMultiplier;
|
||||||
|
|
||||||
|
for (int i = 0; i < numPoints; ++i) {
|
||||||
|
// Berechne X-Position
|
||||||
|
float x = (i / static_cast<float>(numPoints)) * analyzerWidth;
|
||||||
|
|
||||||
|
// Berechne Frequenz (logarithmisch)
|
||||||
|
float normalizedX = i / static_cast<float>(numPoints);
|
||||||
|
float logMin = std::log10(minFreq);
|
||||||
|
float logMax = std::log10(maxFreq);
|
||||||
|
float logFreq = logMin + normalizedX * (logMax - logMin);
|
||||||
|
float freq = std::pow(10.0f, logFreq);
|
||||||
|
|
||||||
|
// Finde Bin und interpoliere
|
||||||
|
float exactBin = freq / deltaF;
|
||||||
|
|
||||||
|
float dB = getInterpolatedDb(exactBin);
|
||||||
|
|
||||||
|
// Normalisiere
|
||||||
|
float normalized = (dB - minDb) / dbRange;
|
||||||
|
normalized = juce::jlimit(0.0f, 1.0f, normalized);
|
||||||
|
|
||||||
|
|
||||||
|
// Berechne Y-Position
|
||||||
|
float pixelHeight = normalized * analyzerHeight;
|
||||||
|
float y = analyzerBottom - pixelHeight;
|
||||||
|
|
||||||
|
// Füge zum Path hinzu
|
||||||
|
if (!pathStarted) {
|
||||||
|
spectrumPath.startNewSubPath(x + analyzerRect.getX(), y);
|
||||||
|
pathStarted = true;
|
||||||
|
} else {
|
||||||
|
spectrumPath.lineTo(x + analyzerRect.getX(), y);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zeichne die Linie mit Anti-Aliasing
|
||||||
|
if (pathStarted) {
|
||||||
|
juce::PathStrokeType stroke(2.0f);
|
||||||
|
stroke.setJointStyle(juce::PathStrokeType::curved); // Runde Ecken
|
||||||
|
g.strokePath(spectrumPath, stroke);
|
||||||
|
|
||||||
|
spectrumPath.lineTo(analyzerRect.getRight(), analyzerBottom);
|
||||||
|
spectrumPath.lineTo(analyzerRect.getX(), analyzerBottom);
|
||||||
|
spectrumPath.closeSubPath();
|
||||||
|
|
||||||
|
g.setColour(Colours::ACCENTCOLOUR.withAlpha(0.3f));
|
||||||
|
g.fillPath(spectrumPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Optional: Zeichne Frequenz-Grid-Linien
|
||||||
|
drawFrequencyGrid(g, dbRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
float CrystalizerEQAudioProcessorEditor::mapFrequencyToX(float freq, float minFreq, float maxFreq, float width) {
|
||||||
|
// Logarithmische Skalierung: log(freq) zwischen log(minFreq) und log(maxFreq)
|
||||||
|
float logMin = std::log10(minFreq);
|
||||||
|
float logMax = std::log10(maxFreq);
|
||||||
|
float logFreq = std::log10(freq);
|
||||||
|
|
||||||
|
float normalized = (logFreq - logMin) / (logMax - logMin);
|
||||||
|
return normalized * width;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CrystalizerEQAudioProcessorEditor::drawFrequencyGrid(juce::Graphics& g, const float dbRange) {
|
||||||
|
g.setColour(Colours::FOREGROUNDCOLOUR.withAlpha(0.3f));
|
||||||
|
|
||||||
|
const float minFreq = spectrumAnalyzer.MINFREQ;
|
||||||
|
const float maxFreq = spectrumAnalyzer.MAXFREQ;
|
||||||
|
const float analyzerWidth = analyzerRect.getWidth();
|
||||||
|
|
||||||
|
const float minDB = spectrumAnalyzer.MINDB;
|
||||||
|
const float maxDB = spectrumAnalyzer.MAXDB;
|
||||||
|
const float analyzerHeight = analyzerRect.getHeight();
|
||||||
|
const float analyzerBottom = analyzerRect.getBottom();
|
||||||
|
|
||||||
|
std::vector<float> gridFreqs = {0, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000};
|
||||||
|
std::vector<float> gridDB = {0, -12, -24, -36, -48, -60, -72};
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < gridDB.size(); ++i) {
|
||||||
|
float db = gridDB[i];
|
||||||
|
|
||||||
|
// 1: dB normalisieren (wie bei der Kurve)
|
||||||
|
float normalized = (db - minDB) / dbRange;
|
||||||
|
normalized = juce::jlimit(0.0f, 1.0f, normalized);
|
||||||
|
|
||||||
|
// 2: Y-Position wie beim Spektrum berechnen
|
||||||
|
float pixelHeight = normalized * analyzerHeight;
|
||||||
|
float y = analyzerBottom - pixelHeight;
|
||||||
|
|
||||||
|
g.drawHorizontalLine(static_cast<int>(y), static_cast<float>(analyzerRect.getX()), static_cast<float>(analyzerRect.getRight()));
|
||||||
|
g.setFont(Typography::getFont(Typography::Style::Mono, 1.0f));
|
||||||
|
juce::String label = juce::String(gridDB[i]);
|
||||||
|
g.drawText(label, analyzerRect.getX(), y, 30, 15,
|
||||||
|
juce::Justification::centred);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (float freq : gridFreqs) {
|
||||||
|
float x = mapFrequencyToX(freq, minFreq, maxFreq, analyzerWidth);
|
||||||
|
x += analyzerRect.getX();
|
||||||
|
|
||||||
|
g.drawVerticalLine(static_cast<int>(x),
|
||||||
|
static_cast<float>(analyzerRect.getY()),
|
||||||
|
static_cast<float>(analyzerRect.getBottom()));
|
||||||
|
|
||||||
|
// Optional: Frequenz-Label zeichnen
|
||||||
|
if (freq == 20) continue;
|
||||||
|
g.setFont(Typography::getFont(Typography::Style::Mono, 1.0f));
|
||||||
|
juce::String label = (freq >= 1000) ? juce::String(freq / 1000) + "k" : juce::String(freq);
|
||||||
|
g.drawText(label, static_cast<int>(x) - 15, analyzerRect.getY(), 30, 15,
|
||||||
|
juce::Justification::centred);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//endregion paintAnalyzer
|
//endregion paintAnalyzer
|
||||||
|
|
||||||
void CrystalizerEQAudioProcessorEditor::paintModeBoxBorders(juce::Graphics &g) {
|
void CrystalizerEQAudioProcessorEditor::paintModeBoxBorders(juce::Graphics &g) {
|
||||||
@ -861,8 +1101,11 @@ void CrystalizerEQAudioProcessorEditor::paint (juce::Graphics& g)
|
|||||||
auto hBH = hB.getHeight();
|
auto hBH = hB.getHeight();
|
||||||
auto hBPad = ((hBY + mPY) - hBH) / 2;
|
auto hBPad = ((hBY + mPY) - hBH) / 2;
|
||||||
g.fillRect(hBX, hBY, hBW, mPY - hBPad);
|
g.fillRect(hBX, hBY, hBW, mPY - hBPad);
|
||||||
//paintBorderLines(g);
|
|
||||||
|
|
||||||
|
const auto logoArea = hB.toFloat().reduced(hBPad);
|
||||||
|
logoDrawable->drawWithin(g, logoArea,
|
||||||
|
juce::RectanglePlacement::xRight, // oder xLeft, yTop etc.
|
||||||
|
1.0f);
|
||||||
|
|
||||||
g.setColour(Colours::SURFACECOLOUR);
|
g.setColour(Colours::SURFACECOLOUR);
|
||||||
const auto pA = getLocalArea(&presetArea, presetArea.getLocalBounds());
|
const auto pA = getLocalArea(&presetArea, presetArea.getLocalBounds());
|
||||||
@ -871,7 +1114,10 @@ void CrystalizerEQAudioProcessorEditor::paint (juce::Graphics& g)
|
|||||||
auto pAWidth = pA.getWidth();
|
auto pAWidth = pA.getWidth();
|
||||||
auto pAHeight = pA.getHeight();
|
auto pAHeight = pA.getHeight();
|
||||||
g.fillRoundedRectangle(pAX, pAY - 10.f, pAWidth, pAHeight + 10.f, 10.0f);
|
g.fillRoundedRectangle(pAX, pAY - 10.f, pAWidth, pAHeight + 10.f, 10.0f);
|
||||||
//paintBorderLines(g);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const auto fA = getLocalArea(&filterArea, filterArea.getLocalBounds());
|
const auto fA = getLocalArea(&filterArea, filterArea.getLocalBounds());
|
||||||
const int fABorderWidth = 3;
|
const int fABorderWidth = 3;
|
||||||
@ -888,13 +1134,13 @@ void CrystalizerEQAudioProcessorEditor::paint (juce::Graphics& g)
|
|||||||
|
|
||||||
g.setColour(Colours::BACKGROUNDBYPASS);
|
g.setColour(Colours::BACKGROUNDBYPASS);
|
||||||
g.fillRect(fA);
|
g.fillRect(fA);
|
||||||
paintBorderLines(g);
|
|
||||||
|
|
||||||
//paintModeBoxBorders(g);
|
//paintModeBoxBorders(g);
|
||||||
|
|
||||||
g.setColour(Colours::SURFACEBYPASS);
|
g.setColour(Colours::SURFACEBYPASS);
|
||||||
const auto fB = getLocalArea(&footerBar, footerBar.getLocalBounds());
|
const auto fB = getLocalArea(&footerBar, footerBar.getLocalBounds());
|
||||||
g.fillRect(fB);
|
g.fillRect(fB);
|
||||||
|
paintBorderLines(g);
|
||||||
|
|
||||||
|
|
||||||
if constexpr (false) // -> auf false setzen, wenn nicht gebraucht
|
if constexpr (false) // -> auf false setzen, wenn nicht gebraucht
|
||||||
@ -1054,6 +1300,25 @@ void CrystalizerEQAudioProcessorEditor::paintBorderLines(juce::Graphics &g) {
|
|||||||
g.drawVerticalLine(x,center - halfLen, center + halfLen);
|
g.drawVerticalLine(x,center - halfLen, center + halfLen);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
g.setColour(DesignSystem::Colours::SURFACECOLOUR);
|
||||||
|
auto prevRightGlobal = (float) globalControlArea.getRight();
|
||||||
|
for (auto* c : globalControlArea.getChildren()) {
|
||||||
|
if (c == &inputSlider) continue;
|
||||||
|
if (c == &masterBypassButton) continue;
|
||||||
|
|
||||||
|
const auto area = getLocalArea(c, c->getLocalBounds());
|
||||||
|
const float xAvg = ((float) area.getX() - prevRightGlobal) / 2;
|
||||||
|
const int x = area.getX() - xAvg;
|
||||||
|
prevRightGlobal = (float) c->getRight();
|
||||||
|
|
||||||
|
const auto top = (float) area.getY();
|
||||||
|
const auto bot = (float) area.getBottom();
|
||||||
|
|
||||||
|
|
||||||
|
const float center = (top + bot) * 0.5f;
|
||||||
|
const float halfLen = (bot - top) * 0.375f;
|
||||||
|
g.drawVerticalLine(x,center - halfLen, center + halfLen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//endregion paintBorderLines
|
//endregion paintBorderLines
|
||||||
|
|
||||||
@ -1073,6 +1338,7 @@ void CrystalizerEQAudioProcessorEditor::setKnobVisibility() {
|
|||||||
lowBandFreqLabel.setEnabled (lowMode >= 1);
|
lowBandFreqLabel.setEnabled (lowMode >= 1);
|
||||||
lowBandSlopeSlider.setEnabled (lowMode == 1);
|
lowBandSlopeSlider.setEnabled (lowMode == 1);
|
||||||
lowBandSlopeLabel.setEnabled (lowMode == 1);
|
lowBandSlopeLabel.setEnabled (lowMode == 1);
|
||||||
|
lowdBOctLabel.setEnabled (lowMode == 1);
|
||||||
lowBandGainSlider.setEnabled(lowMode >= 2);
|
lowBandGainSlider.setEnabled(lowMode >= 2);
|
||||||
lowBandGainLabel .setEnabled(lowMode >= 2);
|
lowBandGainLabel .setEnabled(lowMode >= 2);
|
||||||
lowBandQSlider .setEnabled(lowMode >= 1);
|
lowBandQSlider .setEnabled(lowMode >= 1);
|
||||||
@ -1090,6 +1356,7 @@ void CrystalizerEQAudioProcessorEditor::setKnobVisibility() {
|
|||||||
highBandFreqLabel.setEnabled (highMode >= 1);
|
highBandFreqLabel.setEnabled (highMode >= 1);
|
||||||
highBandSlopeSlider.setEnabled (highMode == 1);
|
highBandSlopeSlider.setEnabled (highMode == 1);
|
||||||
highBandSlopeLabel.setEnabled (highMode == 1);
|
highBandSlopeLabel.setEnabled (highMode == 1);
|
||||||
|
highdBOctLabel.setEnabled (highMode == 1);
|
||||||
highBandGainSlider.setEnabled(highMode >= 2);
|
highBandGainSlider.setEnabled(highMode >= 2);
|
||||||
highBandGainLabel .setEnabled(highMode >= 2);
|
highBandGainLabel .setEnabled(highMode >= 2);
|
||||||
highBandQSlider .setEnabled(highMode >= 1);
|
highBandQSlider .setEnabled(highMode >= 1);
|
||||||
@ -1140,6 +1407,11 @@ void CrystalizerEQAudioProcessorEditor::timerCallback()
|
|||||||
repaint(analyzerRect);
|
repaint(analyzerRect);
|
||||||
resized();
|
resized();
|
||||||
animateCrystalizeButton();
|
animateCrystalizeButton();
|
||||||
|
|
||||||
|
if (presetMenuSafePtr == nullptr)
|
||||||
|
{
|
||||||
|
presetMenuButton.setToggleState(false, juce::dontSendNotification);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//endregion timerCallback
|
//endregion timerCallback
|
||||||
|
|
||||||
@ -1157,6 +1429,7 @@ void CrystalizerEQAudioProcessorEditor::resized()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const auto testBounds = mainPanel.getLocalBounds();
|
const auto testBounds = mainPanel.getLocalBounds();
|
||||||
const auto testWidth = testBounds.getWidth();
|
const auto testWidth = testBounds.getWidth();
|
||||||
const auto testHeight = testBounds.getHeight();
|
const auto testHeight = testBounds.getHeight();
|
||||||
@ -1220,6 +1493,8 @@ void CrystalizerEQAudioProcessorEditor::setupHeader() {
|
|||||||
|
|
||||||
const float presetAreaWidth = static_cast<float>(bounds.getWidth()) * 0.5f;
|
const float presetAreaWidth = static_cast<float>(bounds.getWidth()) * 0.5f;
|
||||||
|
|
||||||
|
const auto titleWidthCentre = titleLabel.getFont().getStringWidth("Crystalizer") / 4;
|
||||||
|
|
||||||
Layout::GridSpec headerSpec{
|
Layout::GridSpec headerSpec{
|
||||||
/* cols */ { Layout::fr(1), Layout::pxTrack(presetAreaWidth), Layout::fr(1) },
|
/* cols */ { Layout::fr(1), Layout::pxTrack(presetAreaWidth), Layout::fr(1) },
|
||||||
/* rows */ { Layout::fr(1) },
|
/* rows */ { Layout::fr(1) },
|
||||||
@ -1228,8 +1503,9 @@ void CrystalizerEQAudioProcessorEditor::setupHeader() {
|
|||||||
/* pad */ Layout::padding(Spacing::SizeMode::XS)
|
/* pad */ Layout::padding(Spacing::SizeMode::XS)
|
||||||
};
|
};
|
||||||
Layout::grid(bounds, headerSpec, {
|
Layout::grid(bounds, headerSpec, {
|
||||||
Layout::area(titleLabel, 1, 1, 2, 2),
|
|
||||||
Layout::area(presetArea, 1, 2, 2, 3),
|
Layout::area(presetArea, 1, 2, 2, 3),
|
||||||
|
Layout::area(titleLabel, 1, 1, 2, 2)
|
||||||
|
.withMargin(juce::GridItem::Margin(0, 0, 0, titleWidthCentre)),
|
||||||
Layout::area(presetMenu, 1, 3, 2, 4),
|
Layout::area(presetMenu, 1, 3, 2, 4),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1251,11 +1527,12 @@ void CrystalizerEQAudioProcessorEditor::setupHeader() {
|
|||||||
const auto presetAreaBounds = presetArea.getLocalBounds();
|
const auto presetAreaBounds = presetArea.getLocalBounds();
|
||||||
const auto presetBoxWidth = static_cast<float>(presetArea.getWidth());
|
const auto presetBoxWidth = static_cast<float>(presetArea.getWidth());
|
||||||
const auto presetBoxHeight = static_cast<float>(presetArea.getHeight());
|
const auto presetBoxHeight = static_cast<float>(presetArea.getHeight());
|
||||||
|
const float rowHeight = presetBoxHeight * 0.25f;
|
||||||
|
const float iconSize = rowHeight;
|
||||||
|
|
||||||
Layout::GridSpec presetSpec{
|
Layout::GridSpec presetSpec{
|
||||||
/* cols */ { Layout::fr(1), Layout::pxTrack(presetBoxWidth * 0.5f), Layout::fr(1)},
|
/* cols */ { Layout::fr(1), Layout::pxTrack(presetBoxWidth * 0.5f), Layout::fr(1)},
|
||||||
/* rows */ { Layout::pxTrack(presetBoxHeight * 0.25f), Layout::pxTrack(presetBoxHeight * 0.25f)},
|
/* rows */ { Layout::pxTrack(rowHeight), Layout::pxTrack(rowHeight)},
|
||||||
/* colGap */ Spacing::SizeMode::XS,
|
/* colGap */ Spacing::SizeMode::XS,
|
||||||
/* rowGap */ Spacing::SizeMode::XS,
|
/* rowGap */ Spacing::SizeMode::XS,
|
||||||
/* pad */ Layout::padding(Spacing::SizeMode::S)
|
/* pad */ Layout::padding(Spacing::SizeMode::S)
|
||||||
@ -1268,7 +1545,8 @@ void CrystalizerEQAudioProcessorEditor::setupHeader() {
|
|||||||
Layout::area(resetButton, 2, 1, 2, 2),
|
Layout::area(resetButton, 2, 1, 2, 2),
|
||||||
// Menütaste unten rechts (row2, col2)
|
// Menütaste unten rechts (row2, col2)
|
||||||
Layout::area(presetMenuButton, 2, 3, 3, 4)
|
Layout::area(presetMenuButton, 2, 3, 3, 4)
|
||||||
,
|
.withWidth(iconSize)
|
||||||
|
.withHeight(iconSize)
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1394,6 +1672,10 @@ void CrystalizerEQAudioProcessorEditor::setupLowBandLayout() {
|
|||||||
Layout::area(lowBandSlopeLabel, 3, 1, 4, 2)
|
Layout::area(lowBandSlopeLabel, 3, 1, 4, 2)
|
||||||
.withMargin(juce::GridItem::Margin(-offSetToGainTop / 1.5f, 0, 0, 0)),
|
.withMargin(juce::GridItem::Margin(-offSetToGainTop / 1.5f, 0, 0, 0)),
|
||||||
|
|
||||||
|
Layout::area(lowdBOctLabel, 3, 1, 4, 2)
|
||||||
|
.withAlignSelf(juce::GridItem::AlignSelf::center)
|
||||||
|
.withJustifySelf(juce::GridItem::JustifySelf::center),
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1630,6 +1912,10 @@ void CrystalizerEQAudioProcessorEditor::setupHighBandLayout() {
|
|||||||
Layout::area(highBandSlopeLabel, 3, 3, 4, 4)
|
Layout::area(highBandSlopeLabel, 3, 3, 4, 4)
|
||||||
.withMargin(juce::GridItem::Margin(-offSetToGainTop / 1.5f, 0, 0, 0)),
|
.withMargin(juce::GridItem::Margin(-offSetToGainTop / 1.5f, 0, 0, 0)),
|
||||||
|
|
||||||
|
Layout::area(highdBOctLabel, 3, 3, 4, 4)
|
||||||
|
.withAlignSelf(juce::GridItem::AlignSelf::center)
|
||||||
|
.withJustifySelf(juce::GridItem::JustifySelf::center),
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto modeBoxBounds = lowBandModeBox.getLocalBounds();
|
const auto modeBoxBounds = lowBandModeBox.getLocalBounds();
|
||||||
@ -1668,7 +1954,7 @@ void CrystalizerEQAudioProcessorEditor::setupFooter() {
|
|||||||
const auto refH = getReferenceCell()[1];
|
const auto refH = getReferenceCell()[1];
|
||||||
|
|
||||||
Layout::GridSpec footerSpec{
|
Layout::GridSpec footerSpec{
|
||||||
/* cols */ { Layout::fr(1), Layout::fr(1), Layout::pxTrack(footerWidth / 3.0f) },
|
/* cols */ { Layout::fr(1), Layout::fr(1), Layout::fr(1) },
|
||||||
/* rows */ { Layout::fr(1) },
|
/* rows */ { Layout::fr(1) },
|
||||||
/* colGap */ Spacing::SizeMode::XS,
|
/* colGap */ Spacing::SizeMode::XS,
|
||||||
/* rowGap */ Spacing::SizeMode::XS,
|
/* rowGap */ Spacing::SizeMode::XS,
|
||||||
@ -1682,10 +1968,12 @@ void CrystalizerEQAudioProcessorEditor::setupFooter() {
|
|||||||
const auto globalControlAreaWidth = static_cast<float>(globalControlArea.getWidth());
|
const auto globalControlAreaWidth = static_cast<float>(globalControlArea.getWidth());
|
||||||
const auto globalControlAreaHeight = static_cast<float>(globalControlArea.getHeight());
|
const auto globalControlAreaHeight = static_cast<float>(globalControlArea.getHeight());
|
||||||
const auto globalControlColWidth = globalControlAreaWidth / 3.0f;
|
const auto globalControlColWidth = globalControlAreaWidth / 3.0f;
|
||||||
|
const auto sliderRadius = outputSlider.getWidth() / 2.0f;
|
||||||
|
const auto sliderWidth = outputSlider.getWidth();
|
||||||
|
|
||||||
|
|
||||||
Layout::GridSpec globalControlAreaSpec{
|
Layout::GridSpec globalControlAreaSpec{
|
||||||
/* cols */ { Layout::fr(1), Layout::pxTrack(globalControlColWidth), Layout::fr(1) },
|
/* cols */ { Layout::fr(1), Layout::fr(1), Layout::fr(1) },
|
||||||
/* rows */ { Layout::fr(1)},
|
/* rows */ { Layout::fr(1)},
|
||||||
/* colGap */ Spacing::SizeMode::XS,
|
/* colGap */ Spacing::SizeMode::XS,
|
||||||
/* rowGap */ Spacing::SizeMode::XS,
|
/* rowGap */ Spacing::SizeMode::XS,
|
||||||
@ -1694,19 +1982,26 @@ void CrystalizerEQAudioProcessorEditor::setupFooter() {
|
|||||||
Layout::grid(globalControlAreaBounds, globalControlAreaSpec, {
|
Layout::grid(globalControlAreaBounds, globalControlAreaSpec, {
|
||||||
|
|
||||||
//TODO: Bring components closer together
|
//TODO: Bring components closer together
|
||||||
Layout::area(inputSlider, 1, 2, 3, 3)
|
|
||||||
.withWidth(refW * globalMod * 0.8f)
|
Layout::area(outputSlider, 1, 2, 3, 3)
|
||||||
.withHeight(refH * globalMod * 0.8f)
|
.withWidth(refW * globalMod )
|
||||||
|
.withHeight(refH * globalMod )
|
||||||
|
.withMargin(juce::GridItem::Margin(0, 0, 0, sliderRadius * 6))
|
||||||
.withAlignSelf(juce::GridItem::AlignSelf::center)
|
.withAlignSelf(juce::GridItem::AlignSelf::center)
|
||||||
.withJustifySelf(juce::GridItem::JustifySelf::center),
|
.withJustifySelf(juce::GridItem::JustifySelf::center),
|
||||||
Layout::area(outputSlider, 1, 3, 3, 4)
|
|
||||||
.withWidth(refW * globalMod * 0.8f)
|
Layout::area(inputSlider, 1, 1, 3, 2)
|
||||||
.withHeight(refH * globalMod * 0.8f)
|
.withWidth(refW * globalMod )
|
||||||
|
.withHeight(refH * globalMod )
|
||||||
|
.withMargin(juce::GridItem::Margin(0, 0, 0, sliderRadius * 10))
|
||||||
.withAlignSelf(juce::GridItem::AlignSelf::center)
|
.withAlignSelf(juce::GridItem::AlignSelf::center)
|
||||||
.withJustifySelf(juce::GridItem::JustifySelf::center),
|
.withJustifySelf(juce::GridItem::JustifySelf::center),
|
||||||
|
|
||||||
|
|
||||||
Layout::area(masterBypassButton, 1, 1, 3, 2),
|
Layout::area(masterBypassButton, 1, 3, 3, 4)
|
||||||
|
.withWidth(sliderWidth)
|
||||||
|
|
||||||
|
.withMargin(juce::GridItem::Margin(0, 0, 0, sliderRadius * 2)),
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1774,7 +2069,9 @@ void SpectrumAnalyzer::applyWindowOnFftFrame(std::vector<float> &fullFrame) {
|
|||||||
void SpectrumAnalyzer::processWindowedFrame(std::vector<float> &windowedFrame) {
|
void SpectrumAnalyzer::processWindowedFrame(std::vector<float> &windowedFrame) {
|
||||||
if (windowedFrame.size() != FFTSIZE || fftData.size() != FFTSIZE * 2) return;
|
if (windowedFrame.size() != FFTSIZE || fftData.size() != FFTSIZE * 2) return;
|
||||||
fillFftDataFromFrame(windowedFrame);
|
fillFftDataFromFrame(windowedFrame);
|
||||||
fft.performRealOnlyForwardTransform(fftData.data());
|
// fft.performRealOnlyForwardTransform(fftData.data());
|
||||||
|
|
||||||
|
fft.performFrequencyOnlyForwardTransform(fftData.data(), true);
|
||||||
buildMagnitudeSpectrum();
|
buildMagnitudeSpectrum();
|
||||||
convertToDb();
|
convertToDb();
|
||||||
applySmoothing();
|
applySmoothing();
|
||||||
@ -1786,8 +2083,9 @@ void SpectrumAnalyzer::processWindowedFrame(std::vector<float> &windowedFrame) {
|
|||||||
//region fillFftDataFromFrame
|
//region fillFftDataFromFrame
|
||||||
void SpectrumAnalyzer::fillFftDataFromFrame(std::vector<float> &windowedFrame) {
|
void SpectrumAnalyzer::fillFftDataFromFrame(std::vector<float> &windowedFrame) {
|
||||||
for (int n = 0; n < FFTSIZE; ++n) {
|
for (int n = 0; n < FFTSIZE; ++n) {
|
||||||
fftData[2*n] = windowedFrame[n];
|
/*fftData[2*n] = windowedFrame[n];
|
||||||
fftData[2*n + 1] = 0.0f;
|
fftData[2*n + 1] = 0.0f;*/
|
||||||
|
fftData[n] = windowedFrame[n];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//endregion fillFftDataFromFrame
|
//endregion fillFftDataFromFrame
|
||||||
@ -1795,17 +2093,9 @@ void SpectrumAnalyzer::fillFftDataFromFrame(std::vector<float> &windowedFrame) {
|
|||||||
//region buildMagnitudeSpectrum
|
//region buildMagnitudeSpectrum
|
||||||
void SpectrumAnalyzer::buildMagnitudeSpectrum() {
|
void SpectrumAnalyzer::buildMagnitudeSpectrum() {
|
||||||
for (int k = 0; k < BINS; ++k) {
|
for (int k = 0; k < BINS; ++k) {
|
||||||
float re = 0.f;
|
float mag = fftData[k];
|
||||||
float im = 0.f;
|
|
||||||
if (k < BINS / 2) {
|
|
||||||
re = fftData[k];
|
|
||||||
} else {
|
|
||||||
im = fftData[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
float mag = sqrt(re * re + im * im);
|
|
||||||
mag /= (FFTSIZE * 0.5f);
|
mag /= (FFTSIZE * 0.5f);
|
||||||
mag = std::max(mag, 1e-12f);
|
mag = std::max(mag, 1e-24f);
|
||||||
magnitudes[k] = mag;
|
magnitudes[k] = mag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1813,9 +2103,14 @@ void SpectrumAnalyzer::buildMagnitudeSpectrum() {
|
|||||||
|
|
||||||
//region convertToDb
|
//region convertToDb
|
||||||
void SpectrumAnalyzer::convertToDb() {
|
void SpectrumAnalyzer::convertToDb() {
|
||||||
|
|
||||||
|
|
||||||
for (int k = 0; k < magnitudes.size(); ++k) {
|
for (int k = 0; k < magnitudes.size(); ++k) {
|
||||||
float mag = magnitudes[k];
|
float mag = magnitudes[k];
|
||||||
float dB = juce::Decibels::gainToDecibels(mag);
|
float dB = juce::Decibels::gainToDecibels(mag);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dB = juce::jlimit(MINDB, MAXDB, dB);
|
dB = juce::jlimit(MINDB, MAXDB, dB);
|
||||||
magnitudesDb[k] = dB;
|
magnitudesDb[k] = dB;
|
||||||
}
|
}
|
||||||
@ -1867,6 +2162,7 @@ void SpectrumAnalyzer::applyFreqSmoothing() {
|
|||||||
float avg = sum / static_cast<float>(highestBin - lowestBin + 1);
|
float avg = sum / static_cast<float>(highestBin - lowestBin + 1);
|
||||||
freqSmoothedMagnitudesDb[k] = avg;
|
freqSmoothedMagnitudesDb[k] = avg;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//endregion applyFreqSmoothing
|
//endregion applyFreqSmoothing
|
||||||
@ -1877,7 +2173,9 @@ void SpectrumAnalyzer::applyPeakHoldAndFalloff() {
|
|||||||
for (int k = 0; k < BINS; ++k) {
|
for (int k = 0; k < BINS; ++k) {
|
||||||
float current = freqSmoothedMagnitudesDb[k];
|
float current = freqSmoothedMagnitudesDb[k];
|
||||||
float prev = prevPeak[k];
|
float prev = prevPeak[k];
|
||||||
|
|
||||||
peakHoldMagnitudesDb[k] = std::max(current, prev - FALLOFFRATE * DELTAT);
|
peakHoldMagnitudesDb[k] = std::max(current, prev - FALLOFFRATE * DELTAT);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//endregion applyPeakHoldAndFalloff
|
//endregion applyPeakHoldAndFalloff
|
||||||
|
|||||||
@ -77,8 +77,8 @@ class SpectrumAnalyzer {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
const float MINDB = -120.f;
|
const float MINDB = -90.f;
|
||||||
const float MAXDB = 96.f;
|
const float MAXDB = 0.f;
|
||||||
|
|
||||||
std::vector<float> magnitudes;
|
std::vector<float> magnitudes;
|
||||||
|
|
||||||
@ -180,21 +180,21 @@ public:
|
|||||||
|
|
||||||
juce::Label titleLabel, testNoiseLabel,
|
juce::Label titleLabel, testNoiseLabel,
|
||||||
lowBandFreqLabel, lowBandSlopeLabel, lowBandGainLabel, lowBandQLabel, lowBandModeLabel,
|
lowBandFreqLabel, lowBandSlopeLabel, lowBandGainLabel, lowBandQLabel, lowBandModeLabel,
|
||||||
low12, low24, low36, low48,
|
low12, low24, low36, low48, lowdBOctLabel,
|
||||||
peak1FreqLabel, peak1GainLabel, peak1QLabel,
|
peak1FreqLabel, peak1GainLabel, peak1QLabel,
|
||||||
peak2FreqLabel, peak2GainLabel, peak2QLabel,
|
peak2FreqLabel, peak2GainLabel, peak2QLabel,
|
||||||
peak3FreqLabel, peak3GainLabel, peak3QLabel,
|
peak3FreqLabel, peak3GainLabel, peak3QLabel,
|
||||||
highBandFreqLabel, highBandSlopeLabel, highBandGainLabel, highBandQLabel, highBandModeLabel,
|
highBandFreqLabel, highBandSlopeLabel, highBandGainLabel, highBandQLabel, highBandModeLabel,
|
||||||
high12, high24, high36, high48,
|
high12, high24, high36, high48, highdBOctLabel,
|
||||||
inputLabel, outputLabel,
|
inputLabel, outputLabel,
|
||||||
presetBoxLabel;
|
presetBoxLabel;
|
||||||
|
|
||||||
const juce::Array<juce::Label*> sliderLabels = {
|
const juce::Array<juce::Label*> sliderLabels = {
|
||||||
&lowBandFreqLabel, &lowBandSlopeLabel, &lowBandGainLabel, &lowBandQLabel, &lowBandModeLabel,
|
&lowBandFreqLabel, &lowBandSlopeLabel, &lowBandGainLabel, &lowBandQLabel, &lowBandModeLabel, &lowdBOctLabel,
|
||||||
&peak1FreqLabel, &peak1GainLabel, &peak1QLabel,
|
&peak1FreqLabel, &peak1GainLabel, &peak1QLabel,
|
||||||
&peak2FreqLabel, &peak2GainLabel, &peak2QLabel,
|
&peak2FreqLabel, &peak2GainLabel, &peak2QLabel,
|
||||||
&peak3FreqLabel, &peak3GainLabel, &peak3QLabel,
|
&peak3FreqLabel, &peak3GainLabel, &peak3QLabel,
|
||||||
&highBandFreqLabel, &highBandSlopeLabel, &highBandGainLabel, &highBandQLabel, &highBandModeLabel,
|
&highBandFreqLabel, &highBandSlopeLabel, &highBandGainLabel, &highBandQLabel, &highBandModeLabel, &highdBOctLabel,
|
||||||
&inputLabel, &outputLabel
|
&inputLabel, &outputLabel
|
||||||
};
|
};
|
||||||
const juce::Array<juce::Label*> slopeLabels = {
|
const juce::Array<juce::Label*> slopeLabels = {
|
||||||
@ -202,10 +202,14 @@ public:
|
|||||||
&high12, &high24, &high36, &high48
|
&high12, &high24, &high36, &high48
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
juce::TextButton testNoiseButton, resetButton, savePresetButton, deletePresetButton;
|
juce::TextButton testNoiseButton, resetButton, savePresetButton, deletePresetButton;
|
||||||
|
|
||||||
juce::ToggleButton masterBypassButton, crystalizeButton, peak1BypassButton, peak2BypassButton, peak3BypassButton, presetMenuButton;
|
juce::ToggleButton masterBypassButton, crystalizeButton, peak1BypassButton, peak2BypassButton, peak3BypassButton, presetMenuButton;
|
||||||
|
|
||||||
|
const juce::Array<juce::ToggleButton*> peakBypassButtons = {&peak1BypassButton, &peak2BypassButton, &peak3BypassButton};
|
||||||
|
|
||||||
juce::ComboBox presetBox;
|
juce::ComboBox presetBox;
|
||||||
|
|
||||||
juce::Component lowBandModeBox, highBandModeBox;
|
juce::Component lowBandModeBox, highBandModeBox;
|
||||||
@ -276,10 +280,10 @@ private:
|
|||||||
std::unique_ptr<Components::PresetMenuButtonLookAndFeel> presetMenuButtonLookAndFeel;
|
std::unique_ptr<Components::PresetMenuButtonLookAndFeel> presetMenuButtonLookAndFeel;
|
||||||
std::unique_ptr<Components::lowBandButtonLookAndFeel> lowBandButtonLookAndFeel;
|
std::unique_ptr<Components::lowBandButtonLookAndFeel> lowBandButtonLookAndFeel;
|
||||||
std::unique_ptr<Components::highBandButtonLookAndFeel> highBandButtonLookAndFeel;
|
std::unique_ptr<Components::highBandButtonLookAndFeel> highBandButtonLookAndFeel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<Components::SvgToggleButtonLookAndFeel> svgToggleButtonLookAndFeel;
|
std::unique_ptr<Components::SvgToggleButtonLookAndFeel> svgToggleButtonLookAndFeel;
|
||||||
|
std::unique_ptr<DesignSystem::PresetMenuLookAndFeel> presetMenuLookAndFeel;
|
||||||
|
std::unique_ptr<DesignSystem::PresetButtonsLookAndFeel> presetButtonLookAndFeel;
|
||||||
|
std::unique_ptr<DesignSystem::PresetComboBoxLookAndFeel> presetComboBoxLookAndFeel;
|
||||||
|
|
||||||
|
|
||||||
//SPECRTRUM ANALYZER
|
//SPECRTRUM ANALYZER
|
||||||
@ -338,5 +342,15 @@ private:
|
|||||||
bool isAnimatingCrystalize = false;
|
bool isAnimatingCrystalize = false;
|
||||||
bool isFadingToActive = false;
|
bool isFadingToActive = false;
|
||||||
|
|
||||||
|
std::unique_ptr<juce::Drawable> logoDrawable;
|
||||||
|
|
||||||
|
DesignSystem::PresetMenu* test;
|
||||||
|
juce::Component::SafePointer<DesignSystem::PresetMenu> presetMenuSafePtr;
|
||||||
|
|
||||||
|
float mapFrequencyToX(float freq, float minFreq, float maxFreq, float width);
|
||||||
|
int getClosestBinForFrequency(float freq);
|
||||||
|
void drawFrequencyGrid(juce::Graphics& g, const float dbRange);
|
||||||
|
float getInterpolatedDb(float exactBin);
|
||||||
|
|
||||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CrystalizerEQAudioProcessorEditor)
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CrystalizerEQAudioProcessorEditor)
|
||||||
};
|
};
|
||||||
|
|||||||
@ -17,7 +17,7 @@ CrystalizerEQAudioProcessor::createParameterLayout() {
|
|||||||
params.push_back (std::make_unique<juce::AudioParameterBool>(
|
params.push_back (std::make_unique<juce::AudioParameterBool>(
|
||||||
"TestNoiseEnabled", "Test Noise Enabled", false));
|
"TestNoiseEnabled", "Test Noise Enabled", false));
|
||||||
|
|
||||||
params.push_back (std::make_unique<juce::AudioParameterFloat>("TestNoiseLevel", "Test Noise Level", juce::NormalisableRange<float>(-60.f, 0.f, 0.1f), -18.f));
|
params.push_back (std::make_unique<juce::AudioParameterFloat>("TestNoiseLevel", "Test Noise Level", juce::NormalisableRange<float>(-60.f, 0.f, 0.1f), 0.f));
|
||||||
|
|
||||||
//LOW-BAND
|
//LOW-BAND
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ CrystalizerEQAudioProcessor::createParameterLayout() {
|
|||||||
"LowBandFreq", "LowBand Freq",
|
"LowBandFreq", "LowBand Freq",
|
||||||
juce::NormalisableRange<float>(20.f, 20000.f, 1.f, 0.5f), 30.f));
|
juce::NormalisableRange<float>(20.f, 20000.f, 1.f, 0.5f), 30.f));
|
||||||
|
|
||||||
params.push_back (std::make_unique<juce::AudioParameterFloat>("LowBandGain", "LowBand Gain", juce::NormalisableRange<float>(-24.f, 24.f, 0.1f), 0.f));
|
params.push_back (std::make_unique<juce::AudioParameterFloat>("LowBandGain", "LowBand Gain", juce::NormalisableRange<float>(-48.f, 48.f, 0.1f), 0.f));
|
||||||
|
|
||||||
params.push_back (std::make_unique<juce::AudioParameterFloat>("LowBandQ", "LowBand Q", juce::NormalisableRange<float>(0.1f, 10.f, 0.01f), 1.f));
|
params.push_back (std::make_unique<juce::AudioParameterFloat>("LowBandQ", "LowBand Q", juce::NormalisableRange<float>(0.1f, 10.f, 0.01f), 1.f));
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ CrystalizerEQAudioProcessor::createParameterLayout() {
|
|||||||
|
|
||||||
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
||||||
"Peak1Gain", "Peak1 Gain (dB)",
|
"Peak1Gain", "Peak1 Gain (dB)",
|
||||||
juce::NormalisableRange<float>(-24.f, 24.f, 0.1f), 0.f));
|
juce::NormalisableRange<float>(-48.f, 48.f, 0.1f), 0.f));
|
||||||
|
|
||||||
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
||||||
"Peak1Q", "Peak1 Q",
|
"Peak1Q", "Peak1 Q",
|
||||||
@ -64,7 +64,7 @@ CrystalizerEQAudioProcessor::createParameterLayout() {
|
|||||||
|
|
||||||
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
||||||
"Peak2Gain", "Peak2 Gain (dB)",
|
"Peak2Gain", "Peak2 Gain (dB)",
|
||||||
juce::NormalisableRange<float>(-24.f, 24.f, 0.1f), 0.f));
|
juce::NormalisableRange<float>(-48.f, 48.f, 0.1f), 0.f));
|
||||||
|
|
||||||
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
||||||
"Peak2Q", "Peak2 Q",
|
"Peak2Q", "Peak2 Q",
|
||||||
@ -81,7 +81,7 @@ CrystalizerEQAudioProcessor::createParameterLayout() {
|
|||||||
|
|
||||||
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
||||||
"Peak3Gain", "Peak3 Gain (dB)",
|
"Peak3Gain", "Peak3 Gain (dB)",
|
||||||
juce::NormalisableRange<float>(-24.f, 24.f, 0.1f), 0.f));
|
juce::NormalisableRange<float>(-48.f, 48.f, 0.1f), 0.f));
|
||||||
|
|
||||||
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
||||||
"Peak3Q", "Peak3 Q",
|
"Peak3Q", "Peak3 Q",
|
||||||
@ -96,7 +96,7 @@ CrystalizerEQAudioProcessor::createParameterLayout() {
|
|||||||
"HighBandFreq", "HighBand Freq",
|
"HighBandFreq", "HighBand Freq",
|
||||||
juce::NormalisableRange<float>(20.f, 20000.f, 1.f, 0.5f), 17000.f));
|
juce::NormalisableRange<float>(20.f, 20000.f, 1.f, 0.5f), 17000.f));
|
||||||
|
|
||||||
params.push_back (std::make_unique<juce::AudioParameterFloat>("HighBandGain", "HighBand Gain", juce::NormalisableRange<float>(-24.f, 24.f, 0.1f), 0.f));
|
params.push_back (std::make_unique<juce::AudioParameterFloat>("HighBandGain", "HighBand Gain", juce::NormalisableRange<float>(-48.f, 48.f, 0.1f), 0.f));
|
||||||
|
|
||||||
params.push_back (std::make_unique<juce::AudioParameterFloat>("HighBandQ", "HighBand Q", juce::NormalisableRange<float>(0.1f, 10.f, 0.01f), 1.f));
|
params.push_back (std::make_unique<juce::AudioParameterFloat>("HighBandQ", "HighBand Q", juce::NormalisableRange<float>(0.1f, 10.f, 0.01f), 1.f));
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user