This commit is contained in:
Armin 2026-08-14 21:48:05 +02:00
commit 831d53380b
4 changed files with 48 additions and 27 deletions

View file

@ -68,7 +68,7 @@ public:
if (branch.isEmpty() || branch == "n/a")
branch = "-";
buildInfo.setText ("Mindball v1.0.0\n"
buildInfo.setText ("Mindball v0.0.5\n"
+ hash + " " + branch + dirty + "\n"
+ juce::String (mindball::BuildInfo::buildTime),
juce::dontSendNotification);
@ -88,9 +88,8 @@ public:
void timerCallback() override
{
const float decay = std::exp (-1.0f / (0.9f * 30.0f));
dryMeter.update (proc.getDryMeterL(), proc.getDryMeterR(), decay);
wetMeter.update (proc.getWetMeterL(), proc.getWetMeterR(), decay);
dryMeter.update (proc.getDryMeterL(), proc.getDryMeterR(), meterDecay);
wetMeter.update (proc.getWetMeterL(), proc.getWetMeterR(), meterDecay);
}
void parameterChanged (const juce::String& paramID, float) override
@ -176,6 +175,8 @@ private:
using SliderAttachment = juce::AudioProcessorValueTreeState::SliderAttachment;
using ButtonAttachment = juce::AudioProcessorValueTreeState::ButtonAttachment;
static constexpr float meterDecay = 0.9636077f; // exp (-1.0f / (0.9f * 30.0f))
MindballAudioProcessor& proc;
static const juce::StringArray syncDivisionNames;

View file

@ -155,18 +155,16 @@ public:
void update (float linL, float linR, float decay)
{
levels[0] = linL;
levels[1] = linR;
peaks[0] = std::max (peaks[0] * decay, linL);
peaks[1] = std::max (peaks[1] * decay, linR);
repaint();
const bool changedL = updateChannel (0, linL, decay);
const bool changedR = updateChannel (1, linR, decay);
if (changedL || changedR)
repaint();
}
void paint (juce::Graphics& g) override
{
constexpr int steps = 15;
constexpr float dbMin = -30.0f;
constexpr float dbPerStep = 2.0f;
auto b = getLocalBounds().toFloat();
g.setColour (MindballColors::textDim);
@ -180,33 +178,55 @@ public:
for (int ch = 0; ch < 2; ++ch)
{
auto row = b.removeFromTop (rowH);
const float lin = std::max (0.0f, levels[ch]);
const float db = 20.0f * std::log10 (lin > 0.0f ? lin : 1e-9f);
const int lit = juce::jlimit (0, steps, juce::roundToInt ((db - dbMin) / dbPerStep));
const int pk = juce::jlimit (0, steps, juce::roundToInt ((20.0f * std::log10 (std::max (1e-9f, peaks[ch])) - dbMin) / dbPerStep));
for (int s = 0; s < steps; ++s)
{
const auto seg = juce::Rectangle<float> (row.getX() + s * (segW + segGap),
row.getY() + 2.0f, segW, rowH - 4.0f);
g.setColour (s < lit ? MindballColors::meterGreen : MindballColors::arcBg);
g.fillRoundedRectangle (seg, 1.0f);
g.setColour (s < lit[ch] ? MindballColors::meterGreen : MindballColors::arcBg);
g.fillRect (seg);
}
if (pk > lit)
if (pk[ch] > 0)
{
const auto seg = juce::Rectangle<float> (row.getX() + pk * (segW + segGap),
const int peakSeg = juce::jmin (pk[ch], steps - 1);
const auto seg = juce::Rectangle<float> (row.getX() + peakSeg * (segW + segGap),
row.getY() + 2.0f, segW, rowH - 4.0f);
g.setColour (MindballColors::meterRed);
g.fillRoundedRectangle (seg, 1.0f);
g.fillRect (seg);
}
}
}
private:
bool updateChannel (int ch, float lin, float decay)
{
peaks[ch] = std::max (peaks[ch] * decay, lin);
const int newLit = levelToSteps (lin);
const int newPk = levelToSteps (peaks[ch]);
if (newLit == lit[ch] && newPk == pk[ch])
return false;
lit[ch] = newLit;
pk[ch] = newPk;
return true;
}
static int levelToSteps (float lin)
{
constexpr int steps = 15;
constexpr float dbMin = -30.0f;
constexpr float dbPerStep = 2.0f;
const float db = 20.0f * std::log10 (lin > 0.0f ? lin : 1e-9f);
return juce::jlimit (0, steps, juce::roundToInt ((db - dbMin) / dbPerStep));
}
juce::String name;
float levels[2] = { 0.0f, 0.0f };
float peaks[2] = { 0.0f, 0.0f };
int lit[2] = { 0, 0 };
int pk[2] = { 0, 0 };
float peaks[2] = { 0.0f, 0.0f };
};
// --------------------------------------------------------------------------------