Skip to content

Commit 9bcfec4

Browse files
committed
smoothed the gain slider and made the volume lower and frequency slider now works.
1 parent 80baf4e commit 9bcfec4

File tree

5 files changed

+85
-57
lines changed

5 files changed

+85
-57
lines changed

source/Oscillator.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
void Oscillator::prepare (double newSampleRate)
1111
{
1212
sampleRate = (newSampleRate > 0.0) ? newSampleRate : 44100.0;
13+
gain.reset (sampleRate, 0.02); // 20 ms ramp time
1314
reset();
1415
}
1516

@@ -20,7 +21,7 @@ void Oscillator::setFrequency (float newFrequency)
2021

2122
void Oscillator::setGain (float newGain)
2223
{
23-
gain = std::max (0.0f, newGain);
24+
gain.setTargetValue (std::max (0.0f, newGain));
2425
}
2526

2627
void Oscillator::reset()
@@ -31,7 +32,7 @@ void Oscillator::reset()
3132
float Oscillator::getNextSineSample()
3233
{
3334
const float outputSample =
34-
std::sin (phase * juce::MathConstants<float>::twoPi) * gain;
35+
std::sin (phase * juce::MathConstants<float>::twoPi) * gain.getNextValue();
3536

3637
phase += frequency / static_cast<float> (sampleRate);
3738
if (phase >= 1.0f)
@@ -42,7 +43,7 @@ float Oscillator::getNextSineSample()
4243

4344
float Oscillator::getNextSawSample()
4445
{
45-
const float outputSample = (2.0f * phase - 1.0f) * gain;
46+
const float outputSample = (2.0f * phase - 1.0f) * gain.getNextValue();
4647

4748
phase += frequency / static_cast<float> (sampleRate);
4849
if (phase >= 1.0f)

source/Oscillator.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#pragma once
66

7+
#include <juce_audio_basics/juce_audio_basics.h>
8+
79
class Oscillator
810
{
911
public:
@@ -18,5 +20,5 @@ class Oscillator
1820
double sampleRate = 44100.0;
1921
float phase = 0.0f;
2022
float frequency = 220.0f;
21-
float gain = 0.15f;
23+
juce::SmoothedValue<float> gain { 0.05f };
2224
};

source/PluginEditor.cpp

Lines changed: 67 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,29 @@
22

33
#include <cmath>
44

5+
void PluginEditor::setupSlider (juce::Slider& slider,
6+
juce::Label& label,
7+
const juce::String& name,
8+
double min, double max, double step, double initialValue,
9+
std::function<void()> onChange,
10+
double skewMidPoint)
11+
{
12+
label.setText (name, juce::dontSendNotification);
13+
label.attachToComponent (&slider, true);
14+
addAndMakeVisible (label);
15+
16+
slider.setSliderStyle (juce::Slider::LinearHorizontal);
17+
slider.setTextBoxStyle (juce::Slider::TextBoxRight, false, 80, 24);
18+
slider.setRange (min, max, step);
19+
20+
if (skewMidPoint > 0.0)
21+
slider.setSkewFactorFromMidPoint (skewMidPoint);
22+
23+
slider.setValue (initialValue);
24+
slider.onValueChange = std::move (onChange);
25+
addAndMakeVisible (slider);
26+
}
27+
528
PluginEditor::PluginEditor (PluginProcessor& p)
629
: AudioProcessorEditor (&p), processorRef (p)
730
{
@@ -18,37 +41,18 @@ PluginEditor::PluginEditor (PluginProcessor& p)
1841
inspector->setVisible (true);
1942
};
2043

21-
frequencyLabel.setText ("Frequency", juce::dontSendNotification);
22-
frequencyLabel.attachToComponent (&frequencySlider, false);
23-
addAndMakeVisible (frequencyLabel);
44+
// --- Frequency slider ---
45+
setupSlider (frequencySlider, frequencyLabel, "Frequency",
46+
20.0, 2000.0, 0.01, processorRef.getFrequency(),
47+
[this] { processorRef.setFrequency (static_cast<float> (frequencySlider.getValue())); repaint(); },
48+
220.0);
2449

25-
frequencySlider.setSliderStyle (juce::Slider::LinearHorizontal);
26-
frequencySlider.setTextBoxStyle (juce::Slider::TextBoxRight, false, 80, 24);
27-
frequencySlider.setRange (20.0, 2000.0, 0.01);
28-
frequencySlider.setSkewFactorFromMidPoint (220.0);
29-
frequencySlider.setValue (processorRef.getFrequency());
30-
frequencySlider.onValueChange = [this]
31-
{
32-
processorRef.setFrequency (static_cast<float> (frequencySlider.getValue()));
33-
repaint();
34-
};
35-
addAndMakeVisible (frequencySlider);
36-
37-
gainLabel.setText ("Gain", juce::dontSendNotification);
38-
gainLabel.attachToComponent (&gainSlider, false);
39-
addAndMakeVisible (gainLabel);
40-
41-
gainSlider.setSliderStyle (juce::Slider::LinearHorizontal);
42-
gainSlider.setTextBoxStyle (juce::Slider::TextBoxRight, false, 80, 24);
43-
gainSlider.setRange (0.0, 1.0, 0.001);
44-
gainSlider.setValue (processorRef.getGain());
45-
gainSlider.onValueChange = [this]
46-
{
47-
processorRef.setGain (static_cast<float> (gainSlider.getValue()));
48-
repaint();
49-
};
50-
addAndMakeVisible (gainSlider);
50+
// --- Gain slider ---
51+
setupSlider (gainSlider, gainLabel, "Gain",
52+
0.0, 1.0, 0.001, processorRef.getGain(),
53+
[this] { processorRef.setGain (static_cast<float> (gainSlider.getValue())); repaint(); });
5154

55+
// --- Waveform selector ---
5256
waveformLabel.setText ("Waveform", juce::dontSendNotification);
5357
addAndMakeVisible (waveformLabel);
5458

@@ -57,11 +61,9 @@ PluginEditor::PluginEditor (PluginProcessor& p)
5761
waveformBox.setSelectedId (processorRef.getWaveform() == PluginProcessor::Waveform::sine ? 1 : 2);
5862
waveformBox.onChange = [this]
5963
{
60-
const auto selectedWaveform = waveformBox.getSelectedId() == 1
64+
processorRef.setWaveform (waveformBox.getSelectedId() == 1
6165
? PluginProcessor::Waveform::sine
62-
: PluginProcessor::Waveform::saw;
63-
64-
processorRef.setWaveform (selectedWaveform);
66+
: PluginProcessor::Waveform::saw);
6567
repaint();
6668
};
6769
addAndMakeVisible (waveformBox);
@@ -70,8 +72,7 @@ PluginEditor::PluginEditor (PluginProcessor& p)
7072
}
7173

7274
PluginEditor::~PluginEditor()
73-
{
74-
}
75+
= default;
7576

7677
void PluginEditor::paint (juce::Graphics& g)
7778
{
@@ -120,26 +121,27 @@ void PluginEditor::resized()
120121
inspectButton.setBounds (getLocalBounds().reduced (16).removeFromBottom (40).removeFromRight (140));
121122
}
122123

123-
void PluginEditor::drawWaveformPreview (juce::Graphics& g, juce::Rectangle<int> area)
124+
void PluginEditor::drawWaveformBackground (juce::Graphics& g, const juce::Rectangle<int> area)
124125
{
126+
const auto areaF = area.toFloat();
127+
125128
g.setColour (juce::Colour (0xff2a2a2a));
126-
g.fillRoundedRectangle (area.toFloat(), 8.0f);
129+
g.fillRoundedRectangle (areaF, 8.0f);
127130

128131
g.setColour (juce::Colour (0xff404040));
129-
g.drawRoundedRectangle (area.toFloat(), 8.0f, 1.0f);
130-
131-
const auto left = static_cast<float> (area.getX());
132-
const auto right = static_cast<float> (area.getRight());
133-
const auto top = static_cast<float> (area.getY());
134-
const auto bottom = static_cast<float> (area.getBottom());
135-
const auto width = static_cast<float> (area.getWidth());
136-
const auto centreY = static_cast<float> (area.getCentreY());
137-
const auto amplitude = static_cast<float> (area.getHeight()) * 0.35f * processorRef.getGain();
132+
g.drawRoundedRectangle (areaF, 8.0f, 1.0f);
138133

139134
g.setColour (juce::Colour (0xff555555));
140-
g.drawHorizontalLine (area.getCentreY(), left, right);
135+
g.drawHorizontalLine (area.getCentreY(),
136+
static_cast<float> (area.getX()),
137+
static_cast<float> (area.getRight()));
138+
}
141139

140+
juce::Path PluginEditor::buildWaveformPath (const juce::Rectangle<int> area, float amplitude) const
141+
{
142142
juce::Path path;
143+
const auto width = static_cast<float> (area.getWidth());
144+
const auto centreY = static_cast<float> (area.getCentreY());
143145

144146
for (int x = 0; x < area.getWidth(); ++x)
145147
{
@@ -158,22 +160,36 @@ void PluginEditor::drawWaveformPreview (juce::Graphics& g, juce::Rectangle<int>
158160
}
159161

160162
const float y = centreY - (sample * amplitude);
161-
const float drawX = static_cast<float> (area.getX() + x);
163+
const auto drawX = static_cast<float> (area.getX() + x);
162164

163165
if (x == 0)
164166
path.startNewSubPath (drawX, y);
165167
else
166168
path.lineTo (drawX, y);
167169
}
168170

169-
g.setColour (juce::Colours::cyan);
170-
g.strokePath (path, juce::PathStrokeType (2.0f));
171+
return path;
172+
}
171173

174+
void PluginEditor::drawWaveformInfoText (juce::Graphics& g, const juce::Rectangle<int> area) const
175+
{
172176
g.setColour (juce::Colours::lightgreen);
173177
g.setFont (13.0f);
174178
g.drawText (
175-
"Freq: " + juce::String (processorRef.getFrequency(), 1) + " Hz Gain: " + juce::String (processorRef.getGain(), 2),
179+
"Freq: " + juce::String (processorRef.getFrequency(), 1)
180+
+ " Hz Gain: " + juce::String (processorRef.getGain(), 2),
176181
area.reduced (10).removeFromBottom (24),
177182
juce::Justification::centredLeft,
178183
false);
184+
}
185+
186+
void PluginEditor::drawWaveformPreview (juce::Graphics& g, const juce::Rectangle<int> area) const
187+
{
188+
drawWaveformBackground (g, area);
189+
190+
const float amplitude = static_cast<float> (area.getHeight()) * 0.35f * processorRef.getGain();
191+
g.setColour (juce::Colours::cyan);
192+
g.strokePath (buildWaveformPath (area, amplitude), juce::PathStrokeType (2.0f));
193+
194+
drawWaveformInfoText (g, area);
179195
}

source/PluginEditor.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,16 @@ class PluginEditor : public juce::AudioProcessorEditor
1616
void resized() override;
1717

1818
private:
19-
void drawWaveformPreview (juce::Graphics& g, juce::Rectangle<int> area);
19+
void setupSlider (juce::Slider& slider, juce::Label& label,
20+
const juce::String& name, double min, double max,
21+
double step, double initialValue,
22+
std::function<void()> onChange,
23+
double skewMidPoint = 0.0);
24+
25+
void drawWaveformPreview (juce::Graphics& g, juce::Rectangle<int> area) const;
26+
static void drawWaveformBackground (juce::Graphics& g, juce::Rectangle<int> area);
27+
juce::Path buildWaveformPath (juce::Rectangle<int> area, float amplitude) const;
28+
void drawWaveformInfoText (juce::Graphics& g, juce::Rectangle<int> area) const;
2029

2130
PluginProcessor& processorRef;
2231
std::unique_ptr<melatonin::Inspector> inspector;

source/PluginProcessor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class PluginProcessor : public juce::AudioProcessor
5656
private:
5757
Oscillator oscillator;
5858
float frequency = 220.0f;
59-
float gain = 0.15f;
59+
float gain = 0.05f;
6060
Waveform waveform = Waveform::saw;
6161

6262
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginProcessor)

0 commit comments

Comments
 (0)