Compare commits
2 Commits
6f2fd49107
...
0eb6325e2e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0eb6325e2e | ||
|
|
da00962842 |
@ -123,11 +123,11 @@ namespace AXIOM {
|
||||
float snappedUnits;
|
||||
switch (mode) {
|
||||
case SnapMode::Nearest: snappedUnits = std::round(units);
|
||||
break;
|
||||
break;
|
||||
case SnapMode::Floor: snappedUnits = std::floor(units + 1e-6f);
|
||||
break;
|
||||
break;
|
||||
case SnapMode::Ceiling: snappedUnits = std::ceil(units - 1e-6f);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
return snappedUnits * grid;
|
||||
};
|
||||
@ -142,15 +142,15 @@ namespace AXIOM {
|
||||
static void setUiScale(uiScaleMode mode) noexcept {
|
||||
switch (mode) {
|
||||
case uiScaleMode::XS: scale.uiScale = 0.5f;
|
||||
break;
|
||||
break;
|
||||
case uiScaleMode::S: scale.uiScale = 0.75f;
|
||||
break;
|
||||
break;
|
||||
case uiScaleMode::M: scale.uiScale = 1.0f;
|
||||
break;
|
||||
break;
|
||||
case uiScaleMode::L: scale.uiScale = 1.5f;
|
||||
break;
|
||||
break;
|
||||
case uiScaleMode::XL: scale.uiScale = 1.75f;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
scale.uiScale = juce::jlimit(0.3f, 3.0f, scale.uiScale);
|
||||
}
|
||||
@ -585,7 +585,7 @@ namespace AXIOM {
|
||||
std::unique_ptr<juce::XmlElement> svgXml;
|
||||
};
|
||||
|
||||
class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
public:
|
||||
PresetMenuButtonLookAndFeel()
|
||||
{
|
||||
@ -605,10 +605,7 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
auto hoverFactor = isHovered ? 1.05f : 1.0f;
|
||||
|
||||
auto iconBounds = juce::Rectangle<float>(iconSize * hoverFactor, iconSize * hoverFactor)
|
||||
.withCentre(bounds.getCentre())
|
||||
.withX(bounds.getX());
|
||||
// ganz links im Button starten
|
||||
;
|
||||
.withCentre(bounds.getCentre());
|
||||
|
||||
float bypassOpacity = 1.0f;
|
||||
|
||||
@ -637,7 +634,7 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
};
|
||||
|
||||
class SvgToggleButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
public:
|
||||
public:
|
||||
SvgToggleButtonLookAndFeel() {
|
||||
passiveSvg = juce::XmlDocument::parse(BinaryData::crystalize_button_passive_icon_svg);
|
||||
activeSvg = juce::XmlDocument::parse(BinaryData::crystalize_button_active_icon_svg);
|
||||
@ -666,22 +663,22 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
|
||||
if (passiveIcon != nullptr && activeIcon != nullptr) {
|
||||
|
||||
activeIcon->drawWithin(g, iconBounds,
|
||||
juce::RectanglePlacement::centred, activeIconOpacity);
|
||||
passiveIcon->drawWithin(g, iconBounds,
|
||||
juce::RectanglePlacement::centred, passiveIconOpacity);
|
||||
activeIcon->drawWithin(g, iconBounds,
|
||||
juce::RectanglePlacement::centred, activeIconOpacity);
|
||||
passiveIcon->drawWithin(g, iconBounds,
|
||||
juce::RectanglePlacement::centred, passiveIconOpacity);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
std::unique_ptr<juce::XmlElement> passiveSvg;
|
||||
std::unique_ptr<juce::XmlElement> activeSvg;
|
||||
|
||||
};
|
||||
|
||||
class lowBandButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
public:
|
||||
public:
|
||||
lowBandButtonLookAndFeel()
|
||||
{
|
||||
lowBypassIcon = juce::XmlDocument::parse(BinaryData::bypass_icon_svg);
|
||||
@ -755,10 +752,6 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
juce::RectanglePlacement::centred, bypassOpacity);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -772,7 +765,7 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
};
|
||||
|
||||
class highBandButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
public:
|
||||
public:
|
||||
highBandButtonLookAndFeel()
|
||||
{
|
||||
highBypassIcon = juce::XmlDocument::parse(BinaryData::bypass_icon_svg);
|
||||
@ -880,6 +873,10 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
juce::Slider::SliderLayout getSliderLayout (juce::Slider& slider) override
|
||||
{
|
||||
juce::Slider::SliderLayout layout;
|
||||
if (slider.getName() == "LowBand Slope" || slider.getName() == "HighBand Slope") {
|
||||
layout.textBoxBounds = {};
|
||||
return layout;
|
||||
}
|
||||
|
||||
auto r = slider.getLocalBounds();
|
||||
|
||||
@ -922,109 +919,110 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
}
|
||||
};
|
||||
class GainSliderLookAndFeel : public BaseSliderLookAndFeel
|
||||
{
|
||||
public:
|
||||
void drawRotarySlider(juce::Graphics& g, int x, int y, int width, int height,
|
||||
float sliderPos, float rotaryStartAngle, float rotaryEndAngle,
|
||||
juce::Slider& slider) override
|
||||
{
|
||||
bool isHovered = slider.isMouseOverOrDragging();
|
||||
auto isEnabled = slider.isEnabled();
|
||||
float hoverFactor = 1.0f;
|
||||
auto surfaceCol = Colours::SURFACECOLOUR;
|
||||
auto accentCol = Colours::ACCENTCOLOUR;
|
||||
if (isEnabled) {
|
||||
surfaceCol = isHovered ? Colours::SURFACEBYPASS : Colours::SURFACECOLOUR;
|
||||
accentCol = isHovered ? Colours::ACCENTHOVER : Colours::ACCENTCOLOUR;
|
||||
hoverFactor = isHovered ? 1.05f : 1.0f;
|
||||
} else {
|
||||
surfaceCol = Colours::SURFACEBYPASS;
|
||||
accentCol = Colours::ACCENTWEAKCOLOUR;
|
||||
}
|
||||
{
|
||||
public:
|
||||
void drawRotarySlider(juce::Graphics& g, int x, int y, int width, int height,
|
||||
float sliderPos, float rotaryStartAngle, float rotaryEndAngle,
|
||||
juce::Slider& slider) override
|
||||
{
|
||||
bool isHovered = slider.isMouseOverOrDragging();
|
||||
auto isEnabled = slider.isEnabled();
|
||||
float hoverFactor = 1.0f;
|
||||
auto surfaceCol = Colours::SURFACECOLOUR;
|
||||
auto accentCol = Colours::ACCENTCOLOUR;
|
||||
if (isEnabled) {
|
||||
surfaceCol = isHovered ? Colours::SURFACEBYPASS : Colours::SURFACECOLOUR;
|
||||
accentCol = isHovered ? Colours::ACCENTHOVER : Colours::ACCENTCOLOUR;
|
||||
hoverFactor = isHovered ? 1.05f : 1.0f;
|
||||
} else {
|
||||
surfaceCol = Colours::SURFACEBYPASS;
|
||||
accentCol = Colours::ACCENTWEAKCOLOUR;
|
||||
}
|
||||
|
||||
auto radius = (juce::jmin(width / 2, height / 2) - 4.0f); // * hoverFactor;
|
||||
auto centreX = x + width * 0.5f;
|
||||
auto centreY = y + height * 0.5f;
|
||||
auto angle = rotaryStartAngle + sliderPos * (rotaryEndAngle - rotaryStartAngle);
|
||||
auto radius = (juce::jmin(width / 2, height / 2) - 4.0f); // * hoverFactor;
|
||||
auto centreX = x + width * 0.5f;
|
||||
auto centreY = y + height * 0.5f;
|
||||
auto angle = rotaryStartAngle + sliderPos * (rotaryEndAngle - rotaryStartAngle);
|
||||
|
||||
auto mid = (rotaryEndAngle - rotaryStartAngle) / 2 + rotaryStartAngle;
|
||||
const float arcPathWidth = 3.0f;
|
||||
auto mid = (rotaryEndAngle - rotaryStartAngle) / 2 + rotaryStartAngle;
|
||||
const float arcPathWidth = 3.0f;
|
||||
|
||||
// Background
|
||||
g.setColour(Colours::BACKGROUNDCOLOUR);
|
||||
g.fillEllipse(centreX - radius, centreY - radius, radius * 2.0f , radius * 2.0f);
|
||||
// Background
|
||||
g.setColour(Colours::BACKGROUNDCOLOUR);
|
||||
g.fillEllipse(centreX - radius, centreY - radius, radius * 2.0f , radius * 2.0f);
|
||||
|
||||
g.setColour(surfaceCol);
|
||||
g.drawEllipse(centreX - radius, centreY - radius, radius * 2.0f, radius * 2.0f, arcPathWidth);
|
||||
g.setColour(surfaceCol);
|
||||
g.drawEllipse(centreX - radius, centreY - radius, radius * 2.0f, radius * 2.0f, arcPathWidth);
|
||||
|
||||
|
||||
// Arc für Gain-Anzeige
|
||||
juce::Path valueArc;
|
||||
valueArc.addCentredArc(centreX, centreY, radius, radius,
|
||||
0.0f, mid, angle, true);
|
||||
// Arc für Gain-Anzeige
|
||||
juce::Path valueArc;
|
||||
valueArc.addCentredArc(centreX, centreY, radius, radius,
|
||||
0.0f, mid, angle, true);
|
||||
|
||||
g.setColour(accentCol);
|
||||
g.strokePath(valueArc, juce::PathStrokeType(arcPathWidth));
|
||||
g.setColour(accentCol);
|
||||
g.strokePath(valueArc, juce::PathStrokeType(arcPathWidth));
|
||||
|
||||
// Pointer
|
||||
juce::Path p;
|
||||
p.addRectangle(-arcPathWidth / 2, (-radius - arcPathWidth) * hoverFactor, arcPathWidth, radius * 0.5f * hoverFactor);
|
||||
p.applyTransform(juce::AffineTransform::rotation(angle).translated(centreX, centreY));
|
||||
g.fillPath(p);
|
||||
// Pointer
|
||||
juce::Path p;
|
||||
p.addRectangle(-arcPathWidth / 2, (-radius - arcPathWidth) * hoverFactor, arcPathWidth, radius * 0.5f * hoverFactor);
|
||||
p.applyTransform(juce::AffineTransform::rotation(angle).translated(centreX, centreY));
|
||||
g.fillPath(p);
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class FreqQSliderLookAndFeel : public BaseSliderLookAndFeel
|
||||
{
|
||||
public:
|
||||
void drawRotarySlider(juce::Graphics& g, int x, int y, int width, int height,
|
||||
float sliderPos, float rotaryStartAngle, float rotaryEndAngle,
|
||||
juce::Slider& slider) override
|
||||
{
|
||||
auto radius = juce::jmin(width / 2, height / 2) - 4.0f;
|
||||
auto centreX = x + width * 0.5f;
|
||||
auto centreY = y + height * 0.5f;
|
||||
auto angle = rotaryStartAngle + sliderPos * (rotaryEndAngle - rotaryStartAngle);
|
||||
const float arcPathWidth = 2.0f;
|
||||
bool isHovered = slider.isMouseOverOrDragging();
|
||||
bool isEnabled = slider.isEnabled();
|
||||
float hoverFactor = 1.0f;
|
||||
auto surfaceCol = Colours::SURFACECOLOUR;
|
||||
auto accentCol = Colours::ACCENTCOLOUR;
|
||||
if (isEnabled) {
|
||||
surfaceCol = isHovered ? Colours::SURFACEBYPASS : Colours::SURFACECOLOUR;
|
||||
accentCol = isHovered ? Colours::ACCENTHOVER : Colours::ACCENTCOLOUR;
|
||||
hoverFactor = isHovered ? 1.05f : 1.0f;
|
||||
} else {
|
||||
surfaceCol = Colours::SURFACEBYPASS;
|
||||
accentCol = Colours::ACCENTWEAKCOLOUR;
|
||||
}
|
||||
{
|
||||
public:
|
||||
void drawRotarySlider(juce::Graphics& g, int x, int y, int width, int height,
|
||||
float sliderPos, float rotaryStartAngle, float rotaryEndAngle,
|
||||
juce::Slider& slider) override
|
||||
{
|
||||
auto radius = juce::jmin(width / 2, height / 2) - 4.0f;
|
||||
auto centreX = x + width * 0.5f;
|
||||
auto centreY = y + height * 0.5f;
|
||||
auto angle = rotaryStartAngle + sliderPos * (rotaryEndAngle - rotaryStartAngle);
|
||||
const float arcPathWidth = 2.0f;
|
||||
bool isHovered = slider.isMouseOverOrDragging();
|
||||
bool isEnabled = slider.isEnabled();
|
||||
float hoverFactor = 1.0f;
|
||||
auto surfaceCol = Colours::SURFACECOLOUR;
|
||||
auto accentCol = Colours::ACCENTCOLOUR;
|
||||
if (isEnabled) {
|
||||
surfaceCol = isHovered ? Colours::SURFACEBYPASS : Colours::SURFACECOLOUR;
|
||||
accentCol = isHovered ? Colours::ACCENTHOVER : Colours::ACCENTCOLOUR;
|
||||
hoverFactor = isHovered ? 1.05f : 1.0f;
|
||||
} else {
|
||||
surfaceCol = Colours::SURFACEBYPASS;
|
||||
accentCol = Colours::ACCENTWEAKCOLOUR;
|
||||
}
|
||||
|
||||
|
||||
// Einfacher Ring
|
||||
g.setColour(surfaceCol);
|
||||
g.drawEllipse(centreX - radius, centreY - radius, radius * 2.0f, radius * 2.0f, 2.0f);
|
||||
// Einfacher Ring
|
||||
g.setColour(surfaceCol);
|
||||
g.drawEllipse(centreX - radius, centreY - radius, radius * 2.0f, radius * 2.0f, 2.0f);
|
||||
|
||||
juce::Path valueArc;
|
||||
valueArc.addCentredArc(centreX, centreY, radius, radius,
|
||||
0.0f, rotaryStartAngle, angle, true);
|
||||
juce::Path valueArc;
|
||||
valueArc.addCentredArc(centreX, centreY, radius, radius,
|
||||
0.0f, rotaryStartAngle, angle, true);
|
||||
|
||||
g.setColour(accentCol);
|
||||
g.strokePath(valueArc, juce::PathStrokeType(arcPathWidth));
|
||||
// Dünner Pointer
|
||||
juce::Path p;
|
||||
p.addRectangle(-1.0f, (-radius - arcPathWidth) * hoverFactor, arcPathWidth, radius * 0.4f * hoverFactor);
|
||||
p.applyTransform(juce::AffineTransform::rotation(angle).translated(centreX, centreY));
|
||||
g.setColour(accentCol);
|
||||
g.strokePath(valueArc, juce::PathStrokeType(arcPathWidth));
|
||||
// Dünner Pointer
|
||||
juce::Path p;
|
||||
p.addRectangle(-1.0f, (-radius - arcPathWidth) * hoverFactor, arcPathWidth, radius * 0.4f * hoverFactor);
|
||||
p.applyTransform(juce::AffineTransform::rotation(angle).translated(centreX, centreY));
|
||||
|
||||
g.setColour(accentCol);
|
||||
g.fillPath(p);
|
||||
}
|
||||
};
|
||||
g.setColour(accentCol);
|
||||
g.fillPath(p);
|
||||
}
|
||||
};
|
||||
|
||||
class SlopeSliderLookAndFeel : public BaseSliderLookAndFeel {
|
||||
public:
|
||||
static constexpr float labelPadding = 20.0f;
|
||||
|
||||
juce::Slider::SliderLayout getSliderLayout(juce::Slider& slider) override
|
||||
{
|
||||
juce::Slider::SliderLayout layout;
|
||||
@ -1119,53 +1117,58 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
};
|
||||
|
||||
class GlobalSliderLookAndFeel : public BaseSliderLookAndFeel
|
||||
{
|
||||
public:
|
||||
void drawRotarySlider(juce::Graphics& g, int x, int y, int width, int height,
|
||||
float sliderPos, float rotaryStartAngle, float rotaryEndAngle,
|
||||
juce::Slider& slider) override
|
||||
{
|
||||
auto radius = juce::jmin(width / 2, height / 2) - 4.0f;
|
||||
auto centreX = x + width * 0.5f;
|
||||
auto centreY = y + height * 0.5f;
|
||||
auto angle = rotaryStartAngle + sliderPos * (rotaryEndAngle - rotaryStartAngle);
|
||||
const float arcPathWidth = 2.0f;
|
||||
auto mid = (rotaryEndAngle - rotaryStartAngle) / 2 + rotaryStartAngle;
|
||||
bool isHovered = slider.isMouseOverOrDragging();
|
||||
bool isEnabled = slider.isEnabled();
|
||||
float hoverFactor = 1.0f;
|
||||
auto surfaceCol = Colours::SURFACECOLOUR;
|
||||
auto accentCol = Colours::ACCENTCOLOUR;
|
||||
if (isEnabled) {
|
||||
surfaceCol = isHovered ? Colours::SURFACEBYPASS : Colours::SURFACECOLOUR;
|
||||
accentCol = isHovered ? Colours::ACCENTHOVER : Colours::ACCENTCOLOUR;
|
||||
hoverFactor = isHovered ? 1.05f : 1.0f;
|
||||
} else {
|
||||
surfaceCol = Colours::SURFACEBYPASS;
|
||||
accentCol = Colours::ACCENTWEAKCOLOUR;
|
||||
}
|
||||
{
|
||||
public:
|
||||
void drawRotarySlider(juce::Graphics& g, int x, int y, int width, int height,
|
||||
float sliderPos, float rotaryStartAngle, float rotaryEndAngle,
|
||||
juce::Slider& slider) override
|
||||
{
|
||||
auto radius = juce::jmin(width / 2, height / 2) - 4.0f;
|
||||
auto centreX = x + width * 0.5f;
|
||||
auto centreY = y + height * 0.5f;
|
||||
auto angle = rotaryStartAngle + sliderPos * (rotaryEndAngle - rotaryStartAngle);
|
||||
const float arcPathWidth = 2.0f;
|
||||
auto mid = (rotaryEndAngle - rotaryStartAngle) / 2 + rotaryStartAngle;
|
||||
bool isHovered = slider.isMouseOverOrDragging();
|
||||
bool isEnabled = slider.isEnabled();
|
||||
float hoverFactor = 1.0f;
|
||||
auto surfaceCol = Colours::SURFACECOLOUR;
|
||||
auto accentCol = Colours::ACCENTCOLOUR;
|
||||
auto ringCol = Colours::SURFACEHOVER;
|
||||
if (isEnabled) {
|
||||
surfaceCol = isHovered ? Colours::SURFACEHOVER : Colours::SURFACECOLOUR;
|
||||
accentCol = isHovered ? Colours::ACCENTHOVER : Colours::ACCENTCOLOUR;
|
||||
ringCol = isHovered ? Colours::SURFACECOLOUR : Colours::SURFACEHOVER;
|
||||
hoverFactor = isHovered ? 1.05f : 1.0f;
|
||||
} else {
|
||||
surfaceCol = Colours::SURFACEBYPASS;
|
||||
accentCol = Colours::ACCENTWEAKCOLOUR;
|
||||
ringCol = Colours::SURFACEHOVER;
|
||||
}
|
||||
|
||||
|
||||
// Einfacher Ring
|
||||
g.setColour(surfaceCol);
|
||||
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);
|
||||
// Einfacher Ring
|
||||
g.setColour(surfaceCol);
|
||||
g.fillEllipse(centreX - radius, centreY - radius, radius * 2.0f , radius * 2.0f);
|
||||
|
||||
juce::Path valueArc;
|
||||
valueArc.addCentredArc(centreX, centreY, radius, radius,
|
||||
0.0f, mid, angle, true);
|
||||
g.setColour(ringCol);
|
||||
g.drawEllipse(centreX - radius, centreY - radius, radius * 2.0f, radius * 2.0f, arcPathWidth);
|
||||
|
||||
g.setColour(accentCol);
|
||||
g.strokePath(valueArc, juce::PathStrokeType(arcPathWidth));
|
||||
// Dünner Pointer
|
||||
juce::Path p;
|
||||
p.addRectangle(-1.0f, (-radius - arcPathWidth) * hoverFactor, arcPathWidth, radius * 0.4f * hoverFactor);
|
||||
p.applyTransform(juce::AffineTransform::rotation(angle).translated(centreX, centreY));
|
||||
juce::Path valueArc;
|
||||
valueArc.addCentredArc(centreX, centreY, radius, radius,
|
||||
0.0f, mid, angle, true);
|
||||
|
||||
g.setColour(accentCol);
|
||||
g.fillPath(p);
|
||||
}
|
||||
};
|
||||
g.setColour(accentCol);
|
||||
g.strokePath(valueArc, juce::PathStrokeType(arcPathWidth));
|
||||
// Dünner Pointer
|
||||
juce::Path p;
|
||||
p.addRectangle(-1.0f, (-radius - arcPathWidth) * hoverFactor, arcPathWidth, radius * 0.4f * hoverFactor);
|
||||
p.applyTransform(juce::AffineTransform::rotation(angle).translated(centreX, centreY));
|
||||
|
||||
g.setColour(accentCol);
|
||||
g.fillPath(p);
|
||||
}
|
||||
};
|
||||
|
||||
struct SliderStyles {
|
||||
struct Size {
|
||||
@ -1183,7 +1186,7 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
case SizeMode::Freq: return 0.8f;
|
||||
case SizeMode::Q: return 0.8f;
|
||||
case SizeMode::Slope: return 0.7f;
|
||||
case SizeMode::Global: return 1.0f;
|
||||
case SizeMode::Global: return 0.8f;
|
||||
case SizeMode::Mix: return 0.8f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
@ -1231,17 +1234,17 @@ class PresetMenuButtonLookAndFeel : public juce::LookAndFeel_V4 {
|
||||
float basisPx = -1.f,
|
||||
Spacing::SizeMode margin = Spacing::SizeMode::XS) {
|
||||
|
||||
juce::FlexItem item{ component };
|
||||
item.flexGrow = flexGrow;
|
||||
item.flexShrink = flexShrink;
|
||||
juce::FlexItem item{ component };
|
||||
item.flexGrow = flexGrow;
|
||||
item.flexShrink = flexShrink;
|
||||
|
||||
if (basisPx >= 0.f)
|
||||
item.flexBasis = basisPx;
|
||||
if (basisPx >= 0.f)
|
||||
item.flexBasis = basisPx;
|
||||
|
||||
const float half = (float) gap(margin) * 0.5f;
|
||||
item.margin = juce::FlexItem::Margin{ half, half, half, half };
|
||||
const float half = (float) gap(margin) * 0.5f;
|
||||
item.margin = juce::FlexItem::Margin{ half, half, half, half };
|
||||
|
||||
return item;
|
||||
return item;
|
||||
}
|
||||
|
||||
static void flexRow(juce::Rectangle<int> bounds,
|
||||
@ -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-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\high_cut_icon.svg"/>
|
||||
<None Include="..\..\Resources\Icons\high_shelf_icon.svg"/>
|
||||
|
||||
@ -74,6 +74,9 @@
|
||||
<None Include="..\..\Resources\Fonts\Roboto-Regular.ttf">
|
||||
<Filter>CrystalizerEQ\Resources\Fonts</Filter>
|
||||
</None>
|
||||
<None Include="..\..\Resources\Icons\logo_icon.svg">
|
||||
<Filter>CrystalizerEQ\Resources\Icons</Filter>
|
||||
</None>
|
||||
<None Include="..\..\Resources\Icons\bell_icon.svg">
|
||||
<Filter>CrystalizerEQ\Resources\Icons</Filter>
|
||||
</None>
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
file="Resources/Fonts/Roboto-Regular.ttf"/>
|
||||
</GROUP>
|
||||
<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="KOfMYl" name="high_cut_icon.svg" compile="0" resource="1"
|
||||
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;
|
||||
|
||||
//================== bell_icon.svg ==================
|
||||
//================== logo_icon.svg ==================
|
||||
static const unsigned char temp_binary_data_7[] =
|
||||
"<?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"
|
||||
" <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"
|
||||
"</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 ==================
|
||||
static const unsigned char temp_binary_data_8[] =
|
||||
static const unsigned char temp_binary_data_9[] =
|
||||
"<?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"
|
||||
" <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"
|
||||
"<svg id=\"Ebene_2\" data-name=\"Ebene 2\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29.49 36.9\">\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>";
|
||||
|
||||
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 ==================
|
||||
static const unsigned char temp_binary_data_9[] =
|
||||
static const unsigned char temp_binary_data_10[] =
|
||||
"<?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"
|
||||
" <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"
|
||||
"</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 ==================
|
||||
static const unsigned char temp_binary_data_10[] =
|
||||
static const unsigned char temp_binary_data_11[] =
|
||||
"<?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"
|
||||
" <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"
|
||||
"<svg id=\"Ebene_2\" data-name=\"Ebene 2\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 29.49 36.9\">\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>";
|
||||
|
||||
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 ==================
|
||||
static const unsigned char temp_binary_data_11[] =
|
||||
static const unsigned char temp_binary_data_12[] =
|
||||
"<?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"
|
||||
" <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"
|
||||
"</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 ==================
|
||||
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 "
|
||||
"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 ==================
|
||||
static const unsigned char temp_binary_data_13[] =
|
||||
static const unsigned char temp_binary_data_14[] =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 32\">\n"
|
||||
" <g id=\"Ebene_6\" data-name=\"Ebene 6\">\n"
|
||||
@ -11548,10 +11573,10 @@ static const unsigned char temp_binary_data_13[] =
|
||||
" </g>\n"
|
||||
"</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 ==================
|
||||
static const unsigned char temp_binary_data_14[] =
|
||||
static const unsigned char temp_binary_data_15[] =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 32\">\n"
|
||||
" <g id=\"Ebene_6\" data-name=\"Ebene 6\">\n"
|
||||
@ -11629,17 +11654,17 @@ static const unsigned char temp_binary_data_14[] =
|
||||
" </g>\n"
|
||||
"</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 ==================
|
||||
static const unsigned char temp_binary_data_15[] =
|
||||
static const unsigned char temp_binary_data_16[] =
|
||||
"<?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"
|
||||
" <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"
|
||||
"</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);
|
||||
@ -11660,10 +11685,11 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes)
|
||||
case 0xcbceafb3: numBytes = 24668; return OrbitronBold_ttf;
|
||||
case 0x9c8232dc: numBytes = 24716; return OrbitronRegular_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 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 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 0x4df4bf1e: numBytes = 350; return preset_menu_icon_svg;
|
||||
case 0xd842aaab: numBytes = 6343; return crystalize_button_active_icon_svg;
|
||||
@ -11685,6 +11711,7 @@ const char* namedResourceList[] =
|
||||
"OrbitronBold_ttf",
|
||||
"OrbitronRegular_ttf",
|
||||
"RobotoRegular_ttf",
|
||||
"logo_icon_svg",
|
||||
"bell_icon_svg",
|
||||
"high_cut_icon_svg",
|
||||
"high_shelf_icon_svg",
|
||||
@ -11705,6 +11732,7 @@ const char* originalFilenames[] =
|
||||
"Orbitron-Bold.ttf",
|
||||
"Orbitron-Regular.ttf",
|
||||
"Roboto-Regular.ttf",
|
||||
"logo_icon.svg",
|
||||
"bell_icon.svg",
|
||||
"high_cut_icon.svg",
|
||||
"high_shelf_icon.svg",
|
||||
|
||||
@ -29,17 +29,20 @@ namespace BinaryData
|
||||
extern const char* RobotoRegular_ttf;
|
||||
const int RobotoRegular_ttfSize = 146004;
|
||||
|
||||
extern const char* logo_icon_svg;
|
||||
const int logo_icon_svgSize = 1793;
|
||||
|
||||
extern const char* bell_icon_svg;
|
||||
const int bell_icon_svgSize = 397;
|
||||
|
||||
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;
|
||||
const int high_shelf_icon_svgSize = 420;
|
||||
|
||||
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;
|
||||
const int low_shelf_icon_svgSize = 410;
|
||||
@ -57,7 +60,7 @@ namespace BinaryData
|
||||
const int bypass_icon_svgSize = 406;
|
||||
|
||||
// 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.
|
||||
extern const char* namedResourceList[];
|
||||
|
||||
@ -52,6 +52,9 @@ void CrystalizerEQAudioProcessorEditor::setupSliders() {
|
||||
&peak3FreqSlider, &peak3QSlider, &highBandFreqSlider, &highBandQSlider}) {
|
||||
s->setLookAndFeel(freqQLookAndFeel.get());
|
||||
}
|
||||
|
||||
lowBandSlopeSlider.setTextBoxStyle(juce::Slider::NoTextBox, true, 0, 0);
|
||||
highBandSlopeSlider.setTextBoxStyle(juce::Slider::NoTextBox, true, 0, 0);
|
||||
}
|
||||
//endregion setupSliders
|
||||
|
||||
@ -130,7 +133,7 @@ void CrystalizerEQAudioProcessorEditor::setupDisplayNames() {
|
||||
testNoiseSlider.setTextValueSuffix(" Gain");
|
||||
|
||||
//lowBandFreqSlider.setTextValueSuffix ("\nHz");
|
||||
lowBandSlopeSlider.setTextValueSuffix ("\ndB/Oct");
|
||||
//lowBandSlopeSlider.setTextValueSuffix ("\ndB/Oct");
|
||||
lowBandGainSlider.setTextValueSuffix("\ndB");
|
||||
//lowBandQSlider.setTextValueSuffix ("\nQ");
|
||||
|
||||
@ -151,7 +154,7 @@ void CrystalizerEQAudioProcessorEditor::setupDisplayNames() {
|
||||
|
||||
|
||||
//highBandFreqSlider.setTextValueSuffix ("\nHz");
|
||||
highBandSlopeSlider.setTextValueSuffix ("\ndB/Oct");
|
||||
//highBandSlopeSlider.setTextValueSuffix ("\ndB/Oct");
|
||||
highBandGainSlider.setTextValueSuffix("\ndB");
|
||||
// highBandQSlider.setTextValueSuffix ("\nQ");
|
||||
|
||||
@ -329,17 +332,30 @@ void CrystalizerEQAudioProcessorEditor::disableHighBand(const float target) {
|
||||
//region disableEverything
|
||||
void CrystalizerEQAudioProcessorEditor::disableEverything(const float target) {
|
||||
bool isToggled = target <= 0.5f;
|
||||
|
||||
for (auto* s : sliders) {
|
||||
s->setEnabled(isToggled);
|
||||
}
|
||||
for (auto* l : sliderLabels) {
|
||||
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);
|
||||
peak2BypassButton.setEnabled(isToggled);
|
||||
peak3BypassButton.setEnabled(isToggled);
|
||||
|
||||
for (auto*b : peakBypassButtons) {
|
||||
b->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);
|
||||
|
||||
crystalizeButton.setEnabled(isToggled);
|
||||
lowBandModeBox.setEnabled(isToggled);
|
||||
highBandModeBox.setEnabled(isToggled);
|
||||
@ -379,11 +395,7 @@ void CrystalizerEQAudioProcessorEditor::addComponentsToLayout() {
|
||||
presetArea.addAndMakeVisible(presetMenuButton);
|
||||
|
||||
headerBar.addAndMakeVisible(presetMenu);
|
||||
presetMenu.addAndMakeVisible(presetNameInput);
|
||||
presetMenu.addAndMakeVisible(savePresetButton);
|
||||
presetMenu.addAndMakeVisible(deletePresetButton);
|
||||
presetMenu.toFront(true);
|
||||
presetMenu.setVisible(false);
|
||||
|
||||
|
||||
|
||||
addAndMakeVisible(mainPanel);
|
||||
@ -403,8 +415,8 @@ void CrystalizerEQAudioProcessorEditor::addComponentsToLayout() {
|
||||
lowBandModeBox.addAndMakeVisible(lowBell);
|
||||
lowBandModeBox.addAndMakeVisible(lowShelf);
|
||||
lowFilterArea.addAndMakeVisible(lowBandModeBox);
|
||||
lowBandModeButtons.add(&lowBypass, &lowCut, &lowBell, &lowShelf);
|
||||
lowBandBools = {false, false, false, true};
|
||||
lowBandModeButtons.add(&lowBypass, &lowCut, &lowShelf, &lowBell);
|
||||
lowBandBools = {false, false, true, false};
|
||||
|
||||
|
||||
lowFilterArea.addAndMakeVisible(lowBandSlopeLabel);
|
||||
@ -416,7 +428,9 @@ void CrystalizerEQAudioProcessorEditor::addComponentsToLayout() {
|
||||
lowBandSlopeSlider.addAndMakeVisible(low24);
|
||||
lowBandSlopeSlider.addAndMakeVisible(low36);
|
||||
lowBandSlopeSlider.addAndMakeVisible(low48);
|
||||
|
||||
lowFilterArea.addAndMakeVisible(lowBandSlopeSlider);
|
||||
lowFilterArea.addAndMakeVisible(lowdBOctLabel);
|
||||
|
||||
lowFilterArea.addAndMakeVisible(lowBandGainSlider);
|
||||
lowFilterArea.addAndMakeVisible(lowBandQSlider);
|
||||
@ -465,8 +479,8 @@ void CrystalizerEQAudioProcessorEditor::addComponentsToLayout() {
|
||||
highBandModeBox.addAndMakeVisible(highBell);
|
||||
highBandModeBox.addAndMakeVisible(highShelf);
|
||||
highFilterArea.addAndMakeVisible(highBandModeBox);
|
||||
highBandModeButtons.add(&highBypass, &highCut, &highBell, &highShelf);
|
||||
highBandBools = {false, false, false, true};
|
||||
highBandModeButtons.add(&highBypass, &highCut, &highShelf, &highBell);
|
||||
highBandBools = {false, false, true, false};
|
||||
|
||||
highFilterArea.addAndMakeVisible(highBandSlopeLabel);
|
||||
highFilterArea.addAndMakeVisible(highBandGainLabel);
|
||||
@ -478,6 +492,8 @@ void CrystalizerEQAudioProcessorEditor::addComponentsToLayout() {
|
||||
highBandSlopeSlider.addAndMakeVisible(high36);
|
||||
highBandSlopeSlider.addAndMakeVisible(high48);
|
||||
highFilterArea.addAndMakeVisible(highBandSlopeSlider);
|
||||
highFilterArea.addAndMakeVisible(highdBOctLabel);
|
||||
|
||||
|
||||
highFilterArea.addAndMakeVisible(highBandGainSlider);
|
||||
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(outputSlider);
|
||||
globalControlArea.addAndMakeVisible(masterBypassButton);
|
||||
footerBar.addAndMakeVisible(globalControlArea);
|
||||
addAndMakeVisible(footerBar);
|
||||
}
|
||||
//endregion addComponentsToLayout
|
||||
|
||||
@ -518,6 +533,7 @@ void CrystalizerEQAudioProcessorEditor::setupLabels() {
|
||||
setupLabel(low24, "24");
|
||||
setupLabel(low36, "36");
|
||||
setupLabel(low48, "48");
|
||||
setupLabel(lowdBOctLabel, "dB/Oct");
|
||||
|
||||
//PEAK 1
|
||||
setupLabel (peak1FreqLabel,"Low-Mid\nHz");
|
||||
@ -544,6 +560,8 @@ void CrystalizerEQAudioProcessorEditor::setupLabels() {
|
||||
setupLabel(high24, "24");
|
||||
setupLabel(high36, "36");
|
||||
setupLabel(high48, "48");
|
||||
setupLabel(highdBOctLabel, "dB/Oct");
|
||||
|
||||
|
||||
setupLabel(presetBoxLabel, "Presets");
|
||||
|
||||
@ -557,6 +575,9 @@ void CrystalizerEQAudioProcessorEditor::setupFontsWithColours() {
|
||||
Typography::applyToLabel(titleLabel, Typography::Style::Display, 1.f);
|
||||
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) {
|
||||
l->setColour(juce::Label::textColourId, Colours::FOREGROUNDCOLOUR);
|
||||
Typography::applyToLabel(*l, Typography::Style::Mono, 1.f);
|
||||
@ -595,7 +616,6 @@ void CrystalizerEQAudioProcessorEditor::handleLowBandModes() {
|
||||
lowBandModeButtons[j]->setToggleState(false, juce::dontSendNotification);
|
||||
}
|
||||
}
|
||||
|
||||
// Aktuellen aktivieren
|
||||
lowBandBools[i] = true;
|
||||
param->setValueNotifyingHost(param->convertTo0to1((float)i));
|
||||
@ -649,8 +669,26 @@ void CrystalizerEQAudioProcessorEditor::handleHighBandModes() {
|
||||
//region setupEventListeners
|
||||
void CrystalizerEQAudioProcessorEditor::setupEventListeners() {
|
||||
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]() {
|
||||
@ -705,8 +743,21 @@ void CrystalizerEQAudioProcessorEditor::setupEventListeners() {
|
||||
resetButton.onClick = [this]()
|
||||
{
|
||||
audioProcessor.resetAllParameters();
|
||||
if (crystalizeButton.getToggleState()) {
|
||||
isAnimatingCrystalize = true;
|
||||
isFadingToActive = (svgToggleButtonLookAndFeel->activeIconOpacity < 1.0f);
|
||||
}
|
||||
resetAllCheckboxes();
|
||||
for (auto* s : sliders) {
|
||||
s->setEnabled(true);
|
||||
}
|
||||
for (auto* l : sliderLabels) {
|
||||
l->setEnabled(true);
|
||||
}
|
||||
presetBox.setSelectedId(1, juce::dontSendNotification);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
handleLowBandModes();
|
||||
@ -724,6 +775,7 @@ void CrystalizerEQAudioProcessorEditor::initPresetSystem() {
|
||||
presetBox.addItemList(presets, 1);
|
||||
presetBox.setSelectedId(1, juce::dontSendNotification);
|
||||
|
||||
|
||||
presetMenuButton.setName("PresetMenuButton");
|
||||
presetMenuButton.setColour (juce::ToggleButton::textColourId, juce::Colours::black);
|
||||
presetMenuButton.setColour(juce::ToggleButton::tickColourId, juce::Colours::black);
|
||||
@ -733,6 +785,14 @@ void CrystalizerEQAudioProcessorEditor::initPresetSystem() {
|
||||
presetNameInput.setJustification(juce::Justification::centred);
|
||||
presetNameInput.setColour(juce::TextEditor::backgroundColourId, juce::Colours::black);
|
||||
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
|
||||
|
||||
@ -754,6 +814,12 @@ CrystalizerEQAudioProcessorEditor::CrystalizerEQAudioProcessorEditor (Crystalize
|
||||
setupSliders();
|
||||
initPresetSystem();
|
||||
|
||||
|
||||
|
||||
auto logoIcon = juce::XmlDocument::parse (BinaryData::logo_icon_svg);
|
||||
if (logoIcon != nullptr)
|
||||
logoDrawable = juce::Drawable::createFromSVG (*logoIcon);
|
||||
|
||||
addAndMakeVisible (testNoiseButton);
|
||||
|
||||
testNoiseButton.onClick = [this]() {
|
||||
@ -790,6 +856,7 @@ CrystalizerEQAudioProcessorEditor::~CrystalizerEQAudioProcessorEditor() {
|
||||
crystalizeButton.setLookAndFeel(nullptr);
|
||||
presetMenuButton.setLookAndFeel(nullptr);
|
||||
|
||||
|
||||
for (auto* b : lowBandModeButtons) {
|
||||
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
|
||||
void CrystalizerEQAudioProcessorEditor::paintAnalyzer(juce::Graphics &g) {
|
||||
analyzerRect = getLocalArea(&analyzerArea, analyzerArea.getLocalBounds());
|
||||
@ -806,14 +904,156 @@ void CrystalizerEQAudioProcessorEditor::paintAnalyzer(juce::Graphics &g) {
|
||||
|
||||
auto r = analyzerRect.toFloat();
|
||||
|
||||
// Hintergrund des Analyzer-Bereichs
|
||||
// Hintergrund
|
||||
g.setColour(juce::Colours::black);
|
||||
g.fillRect(r);
|
||||
|
||||
// Rahmen (optional)
|
||||
// Rahmen
|
||||
g.setColour(juce::Colours::grey);
|
||||
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
|
||||
|
||||
void CrystalizerEQAudioProcessorEditor::paintModeBoxBorders(juce::Graphics &g) {
|
||||
@ -861,8 +1101,11 @@ void CrystalizerEQAudioProcessorEditor::paint (juce::Graphics& g)
|
||||
auto hBH = hB.getHeight();
|
||||
auto hBPad = ((hBY + mPY) - hBH) / 2;
|
||||
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);
|
||||
const auto pA = getLocalArea(&presetArea, presetArea.getLocalBounds());
|
||||
@ -871,7 +1114,10 @@ void CrystalizerEQAudioProcessorEditor::paint (juce::Graphics& g)
|
||||
auto pAWidth = pA.getWidth();
|
||||
auto pAHeight = pA.getHeight();
|
||||
g.fillRoundedRectangle(pAX, pAY - 10.f, pAWidth, pAHeight + 10.f, 10.0f);
|
||||
//paintBorderLines(g);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const auto fA = getLocalArea(&filterArea, filterArea.getLocalBounds());
|
||||
const int fABorderWidth = 3;
|
||||
@ -888,13 +1134,13 @@ void CrystalizerEQAudioProcessorEditor::paint (juce::Graphics& g)
|
||||
|
||||
g.setColour(Colours::BACKGROUNDBYPASS);
|
||||
g.fillRect(fA);
|
||||
paintBorderLines(g);
|
||||
|
||||
//paintModeBoxBorders(g);
|
||||
|
||||
g.setColour(Colours::SURFACEBYPASS);
|
||||
const auto fB = getLocalArea(&footerBar, footerBar.getLocalBounds());
|
||||
g.fillRect(fB);
|
||||
paintBorderLines(g);
|
||||
|
||||
|
||||
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.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
|
||||
|
||||
@ -1073,6 +1338,7 @@ void CrystalizerEQAudioProcessorEditor::setKnobVisibility() {
|
||||
lowBandFreqLabel.setEnabled (lowMode >= 1);
|
||||
lowBandSlopeSlider.setEnabled (lowMode == 1);
|
||||
lowBandSlopeLabel.setEnabled (lowMode == 1);
|
||||
lowdBOctLabel.setEnabled (lowMode == 1);
|
||||
lowBandGainSlider.setEnabled(lowMode >= 2);
|
||||
lowBandGainLabel .setEnabled(lowMode >= 2);
|
||||
lowBandQSlider .setEnabled(lowMode >= 1);
|
||||
@ -1090,6 +1356,7 @@ void CrystalizerEQAudioProcessorEditor::setKnobVisibility() {
|
||||
highBandFreqLabel.setEnabled (highMode >= 1);
|
||||
highBandSlopeSlider.setEnabled (highMode == 1);
|
||||
highBandSlopeLabel.setEnabled (highMode == 1);
|
||||
highdBOctLabel.setEnabled (highMode == 1);
|
||||
highBandGainSlider.setEnabled(highMode >= 2);
|
||||
highBandGainLabel .setEnabled(highMode >= 2);
|
||||
highBandQSlider .setEnabled(highMode >= 1);
|
||||
@ -1140,6 +1407,11 @@ void CrystalizerEQAudioProcessorEditor::timerCallback()
|
||||
repaint(analyzerRect);
|
||||
resized();
|
||||
animateCrystalizeButton();
|
||||
|
||||
if (presetMenuSafePtr == nullptr)
|
||||
{
|
||||
presetMenuButton.setToggleState(false, juce::dontSendNotification);
|
||||
}
|
||||
}
|
||||
//endregion timerCallback
|
||||
|
||||
@ -1157,6 +1429,7 @@ void CrystalizerEQAudioProcessorEditor::resized()
|
||||
|
||||
|
||||
|
||||
|
||||
const auto testBounds = mainPanel.getLocalBounds();
|
||||
const auto testWidth = testBounds.getWidth();
|
||||
const auto testHeight = testBounds.getHeight();
|
||||
@ -1220,6 +1493,8 @@ void CrystalizerEQAudioProcessorEditor::setupHeader() {
|
||||
|
||||
const float presetAreaWidth = static_cast<float>(bounds.getWidth()) * 0.5f;
|
||||
|
||||
const auto titleWidthCentre = titleLabel.getFont().getStringWidth("Crystalizer") / 4;
|
||||
|
||||
Layout::GridSpec headerSpec{
|
||||
/* cols */ { Layout::fr(1), Layout::pxTrack(presetAreaWidth), Layout::fr(1) },
|
||||
/* rows */ { Layout::fr(1) },
|
||||
@ -1228,8 +1503,9 @@ void CrystalizerEQAudioProcessorEditor::setupHeader() {
|
||||
/* pad */ Layout::padding(Spacing::SizeMode::XS)
|
||||
};
|
||||
Layout::grid(bounds, headerSpec, {
|
||||
Layout::area(titleLabel, 1, 1, 2, 2),
|
||||
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),
|
||||
});
|
||||
|
||||
@ -1251,11 +1527,12 @@ void CrystalizerEQAudioProcessorEditor::setupHeader() {
|
||||
const auto presetAreaBounds = presetArea.getLocalBounds();
|
||||
const auto presetBoxWidth = static_cast<float>(presetArea.getWidth());
|
||||
const auto presetBoxHeight = static_cast<float>(presetArea.getHeight());
|
||||
|
||||
const float rowHeight = presetBoxHeight * 0.25f;
|
||||
const float iconSize = rowHeight;
|
||||
|
||||
Layout::GridSpec presetSpec{
|
||||
/* 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,
|
||||
/* rowGap */ Spacing::SizeMode::XS,
|
||||
/* pad */ Layout::padding(Spacing::SizeMode::S)
|
||||
@ -1268,7 +1545,8 @@ void CrystalizerEQAudioProcessorEditor::setupHeader() {
|
||||
Layout::area(resetButton, 2, 1, 2, 2),
|
||||
// Menütaste unten rechts (row2, col2)
|
||||
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)
|
||||
.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)
|
||||
.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();
|
||||
@ -1668,7 +1954,7 @@ void CrystalizerEQAudioProcessorEditor::setupFooter() {
|
||||
const auto refH = getReferenceCell()[1];
|
||||
|
||||
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) },
|
||||
/* colGap */ Spacing::SizeMode::XS,
|
||||
/* rowGap */ Spacing::SizeMode::XS,
|
||||
@ -1682,10 +1968,12 @@ void CrystalizerEQAudioProcessorEditor::setupFooter() {
|
||||
const auto globalControlAreaWidth = static_cast<float>(globalControlArea.getWidth());
|
||||
const auto globalControlAreaHeight = static_cast<float>(globalControlArea.getHeight());
|
||||
const auto globalControlColWidth = globalControlAreaWidth / 3.0f;
|
||||
const auto sliderRadius = outputSlider.getWidth() / 2.0f;
|
||||
const auto sliderWidth = outputSlider.getWidth();
|
||||
|
||||
|
||||
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)},
|
||||
/* colGap */ Spacing::SizeMode::XS,
|
||||
/* rowGap */ Spacing::SizeMode::XS,
|
||||
@ -1694,19 +1982,26 @@ void CrystalizerEQAudioProcessorEditor::setupFooter() {
|
||||
Layout::grid(globalControlAreaBounds, globalControlAreaSpec, {
|
||||
|
||||
//TODO: Bring components closer together
|
||||
Layout::area(inputSlider, 1, 2, 3, 3)
|
||||
.withWidth(refW * globalMod * 0.8f)
|
||||
.withHeight(refH * globalMod * 0.8f)
|
||||
|
||||
Layout::area(outputSlider, 1, 2, 3, 3)
|
||||
.withWidth(refW * globalMod )
|
||||
.withHeight(refH * globalMod )
|
||||
.withMargin(juce::GridItem::Margin(0, 0, 0, sliderRadius * 6))
|
||||
.withAlignSelf(juce::GridItem::AlignSelf::center)
|
||||
.withJustifySelf(juce::GridItem::JustifySelf::center),
|
||||
Layout::area(outputSlider, 1, 3, 3, 4)
|
||||
.withWidth(refW * globalMod * 0.8f)
|
||||
.withHeight(refH * globalMod * 0.8f)
|
||||
|
||||
Layout::area(inputSlider, 1, 1, 3, 2)
|
||||
.withWidth(refW * globalMod )
|
||||
.withHeight(refH * globalMod )
|
||||
.withMargin(juce::GridItem::Margin(0, 0, 0, sliderRadius * 10))
|
||||
.withAlignSelf(juce::GridItem::AlignSelf::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) {
|
||||
if (windowedFrame.size() != FFTSIZE || fftData.size() != FFTSIZE * 2) return;
|
||||
fillFftDataFromFrame(windowedFrame);
|
||||
fft.performRealOnlyForwardTransform(fftData.data());
|
||||
// fft.performRealOnlyForwardTransform(fftData.data());
|
||||
|
||||
fft.performFrequencyOnlyForwardTransform(fftData.data(), true);
|
||||
buildMagnitudeSpectrum();
|
||||
convertToDb();
|
||||
applySmoothing();
|
||||
@ -1786,8 +2083,9 @@ void SpectrumAnalyzer::processWindowedFrame(std::vector<float> &windowedFrame) {
|
||||
//region fillFftDataFromFrame
|
||||
void SpectrumAnalyzer::fillFftDataFromFrame(std::vector<float> &windowedFrame) {
|
||||
for (int n = 0; n < FFTSIZE; ++n) {
|
||||
fftData[2*n] = windowedFrame[n];
|
||||
fftData[2*n + 1] = 0.0f;
|
||||
/*fftData[2*n] = windowedFrame[n];
|
||||
fftData[2*n + 1] = 0.0f;*/
|
||||
fftData[n] = windowedFrame[n];
|
||||
}
|
||||
}
|
||||
//endregion fillFftDataFromFrame
|
||||
@ -1795,17 +2093,9 @@ void SpectrumAnalyzer::fillFftDataFromFrame(std::vector<float> &windowedFrame) {
|
||||
//region buildMagnitudeSpectrum
|
||||
void SpectrumAnalyzer::buildMagnitudeSpectrum() {
|
||||
for (int k = 0; k < BINS; ++k) {
|
||||
float re = 0.f;
|
||||
float im = 0.f;
|
||||
if (k < BINS / 2) {
|
||||
re = fftData[k];
|
||||
} else {
|
||||
im = fftData[k];
|
||||
}
|
||||
|
||||
float mag = sqrt(re * re + im * im);
|
||||
float mag = fftData[k];
|
||||
mag /= (FFTSIZE * 0.5f);
|
||||
mag = std::max(mag, 1e-12f);
|
||||
mag = std::max(mag, 1e-24f);
|
||||
magnitudes[k] = mag;
|
||||
}
|
||||
}
|
||||
@ -1813,9 +2103,14 @@ void SpectrumAnalyzer::buildMagnitudeSpectrum() {
|
||||
|
||||
//region convertToDb
|
||||
void SpectrumAnalyzer::convertToDb() {
|
||||
|
||||
|
||||
for (int k = 0; k < magnitudes.size(); ++k) {
|
||||
float mag = magnitudes[k];
|
||||
float dB = juce::Decibels::gainToDecibels(mag);
|
||||
|
||||
|
||||
|
||||
dB = juce::jlimit(MINDB, MAXDB, dB);
|
||||
magnitudesDb[k] = dB;
|
||||
}
|
||||
@ -1867,6 +2162,7 @@ void SpectrumAnalyzer::applyFreqSmoothing() {
|
||||
float avg = sum / static_cast<float>(highestBin - lowestBin + 1);
|
||||
freqSmoothedMagnitudesDb[k] = avg;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
//endregion applyFreqSmoothing
|
||||
@ -1877,7 +2173,9 @@ void SpectrumAnalyzer::applyPeakHoldAndFalloff() {
|
||||
for (int k = 0; k < BINS; ++k) {
|
||||
float current = freqSmoothedMagnitudesDb[k];
|
||||
float prev = prevPeak[k];
|
||||
|
||||
peakHoldMagnitudesDb[k] = std::max(current, prev - FALLOFFRATE * DELTAT);
|
||||
|
||||
}
|
||||
}
|
||||
//endregion applyPeakHoldAndFalloff
|
||||
|
||||
@ -77,8 +77,8 @@ class SpectrumAnalyzer {
|
||||
|
||||
|
||||
|
||||
const float MINDB = -120.f;
|
||||
const float MAXDB = 96.f;
|
||||
const float MINDB = -90.f;
|
||||
const float MAXDB = 0.f;
|
||||
|
||||
std::vector<float> magnitudes;
|
||||
|
||||
@ -180,21 +180,21 @@ public:
|
||||
|
||||
juce::Label titleLabel, testNoiseLabel,
|
||||
lowBandFreqLabel, lowBandSlopeLabel, lowBandGainLabel, lowBandQLabel, lowBandModeLabel,
|
||||
low12, low24, low36, low48,
|
||||
low12, low24, low36, low48, lowdBOctLabel,
|
||||
peak1FreqLabel, peak1GainLabel, peak1QLabel,
|
||||
peak2FreqLabel, peak2GainLabel, peak2QLabel,
|
||||
peak3FreqLabel, peak3GainLabel, peak3QLabel,
|
||||
highBandFreqLabel, highBandSlopeLabel, highBandGainLabel, highBandQLabel, highBandModeLabel,
|
||||
high12, high24, high36, high48,
|
||||
high12, high24, high36, high48, highdBOctLabel,
|
||||
inputLabel, outputLabel,
|
||||
presetBoxLabel;
|
||||
|
||||
const juce::Array<juce::Label*> sliderLabels = {
|
||||
&lowBandFreqLabel, &lowBandSlopeLabel, &lowBandGainLabel, &lowBandQLabel, &lowBandModeLabel,
|
||||
&lowBandFreqLabel, &lowBandSlopeLabel, &lowBandGainLabel, &lowBandQLabel, &lowBandModeLabel, &lowdBOctLabel,
|
||||
&peak1FreqLabel, &peak1GainLabel, &peak1QLabel,
|
||||
&peak2FreqLabel, &peak2GainLabel, &peak2QLabel,
|
||||
&peak3FreqLabel, &peak3GainLabel, &peak3QLabel,
|
||||
&highBandFreqLabel, &highBandSlopeLabel, &highBandGainLabel, &highBandQLabel, &highBandModeLabel,
|
||||
&highBandFreqLabel, &highBandSlopeLabel, &highBandGainLabel, &highBandQLabel, &highBandModeLabel, &highdBOctLabel,
|
||||
&inputLabel, &outputLabel
|
||||
};
|
||||
const juce::Array<juce::Label*> slopeLabels = {
|
||||
@ -202,10 +202,14 @@ public:
|
||||
&high12, &high24, &high36, &high48
|
||||
};
|
||||
|
||||
|
||||
|
||||
juce::TextButton testNoiseButton, resetButton, savePresetButton, deletePresetButton;
|
||||
|
||||
juce::ToggleButton masterBypassButton, crystalizeButton, peak1BypassButton, peak2BypassButton, peak3BypassButton, presetMenuButton;
|
||||
|
||||
const juce::Array<juce::ToggleButton*> peakBypassButtons = {&peak1BypassButton, &peak2BypassButton, &peak3BypassButton};
|
||||
|
||||
juce::ComboBox presetBox;
|
||||
|
||||
juce::Component lowBandModeBox, highBandModeBox;
|
||||
@ -276,10 +280,10 @@ private:
|
||||
std::unique_ptr<Components::PresetMenuButtonLookAndFeel> presetMenuButtonLookAndFeel;
|
||||
std::unique_ptr<Components::lowBandButtonLookAndFeel> lowBandButtonLookAndFeel;
|
||||
std::unique_ptr<Components::highBandButtonLookAndFeel> highBandButtonLookAndFeel;
|
||||
|
||||
|
||||
|
||||
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
|
||||
@ -338,5 +342,15 @@ private:
|
||||
bool isAnimatingCrystalize = 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)
|
||||
};
|
||||
|
||||
@ -17,7 +17,7 @@ CrystalizerEQAudioProcessor::createParameterLayout() {
|
||||
params.push_back (std::make_unique<juce::AudioParameterBool>(
|
||||
"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
|
||||
|
||||
@ -25,7 +25,7 @@ CrystalizerEQAudioProcessor::createParameterLayout() {
|
||||
"LowBandFreq", "LowBand Freq",
|
||||
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));
|
||||
|
||||
@ -47,7 +47,7 @@ CrystalizerEQAudioProcessor::createParameterLayout() {
|
||||
|
||||
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
||||
"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>(
|
||||
"Peak1Q", "Peak1 Q",
|
||||
@ -64,7 +64,7 @@ CrystalizerEQAudioProcessor::createParameterLayout() {
|
||||
|
||||
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
||||
"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>(
|
||||
"Peak2Q", "Peak2 Q",
|
||||
@ -81,7 +81,7 @@ CrystalizerEQAudioProcessor::createParameterLayout() {
|
||||
|
||||
params.push_back (std::make_unique<juce::AudioParameterFloat>(
|
||||
"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>(
|
||||
"Peak3Q", "Peak3 Q",
|
||||
@ -96,7 +96,7 @@ CrystalizerEQAudioProcessor::createParameterLayout() {
|
||||
"HighBandFreq", "HighBand Freq",
|
||||
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));
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user