Commit 9df90ef2 authored by Jonathan Hyde's avatar Jonathan Hyde

Update meters

parent f90557da
......@@ -101,7 +101,7 @@ UtilityAudioProcessorEditor::UtilityAudioProcessorEditor (UtilityAudioProcessor&
m_gain.setRange(-35.0f, 35.0f, 0.1f);
m_gain.setMouseCursor(MouseCursor::UpDownResizeCursor);
m_gain.setVelocityBasedMode(false);
m_gain.setVelocityModeParameters(0.5, 0.1, 0.01);
m_gain.setVelocityModeParameters(0.5, 2, 0.01);
m_gain.setValue(Decibels::gainToDecibels(gainParam), NotificationType::dontSendNotification);
m_gain.setDoubleClickReturnValue(true, 0.0f);
m_gain.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
......@@ -113,7 +113,7 @@ UtilityAudioProcessorEditor::UtilityAudioProcessorEditor (UtilityAudioProcessor&
m_pan.setRange(0.0f, 1.0f, 0.01f);
m_pan.setMouseCursor(MouseCursor::UpDownResizeCursor);
m_pan.setVelocityBasedMode(false);
m_pan.setVelocityModeParameters(0.5, 0.1, 0.01);
m_pan.setVelocityModeParameters(0.5, 2, 0.01);
m_pan.setValue(*processor.p_pan, NotificationType::dontSendNotification);
m_pan.setDoubleClickReturnValue(true, 0.5f);
m_pan.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
......@@ -124,7 +124,7 @@ UtilityAudioProcessorEditor::UtilityAudioProcessorEditor (UtilityAudioProcessor&
m_gainL.setSliderStyle(Slider::LinearVertical);
m_gainL.setRange(-35.0f, 35.0f, 0.1f);
m_gainL.setVelocityBasedMode(false);
m_gainL.setVelocityModeParameters(0.5, 0.1, 0.01);
m_gainL.setVelocityModeParameters(0.5, 2, 0.01);
m_gainL.setValue(*processor.p_gainL, NotificationType::dontSendNotification);
m_gainL.setDoubleClickReturnValue(true, 0.0f);
m_gainL.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
......@@ -134,7 +134,7 @@ UtilityAudioProcessorEditor::UtilityAudioProcessorEditor (UtilityAudioProcessor&
m_gainR.setSliderStyle(Slider::LinearVertical);
m_gainR.setRange(-35.0f, 35.0f, 0.1f);
m_gainR.setVelocityBasedMode(false);
m_gainR.setVelocityModeParameters(0.5, 0.1, 0.01);
m_gainR.setVelocityModeParameters(0.5, 2, 0.01);
m_gainR.setValue(*processor.p_gainR, NotificationType::dontSendNotification);
m_gainR.setDoubleClickReturnValue(true, 0.0f);
m_gainR.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
......@@ -144,7 +144,7 @@ UtilityAudioProcessorEditor::UtilityAudioProcessorEditor (UtilityAudioProcessor&
m_gainM.setSliderStyle(Slider::LinearVertical);
m_gainM.setRange(-60.0f, 20.0f, 0.1f);
m_gainM.setVelocityBasedMode(false);
m_gainM.setVelocityModeParameters(0.5, 0.1, 0.01);
m_gainM.setVelocityModeParameters(0.5, 2, 0.01);
m_gainM.setValue(*processor.p_gainM, NotificationType::dontSendNotification);
m_gainM.setDoubleClickReturnValue(true, 0.0f);
m_gainM.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
......@@ -154,7 +154,7 @@ UtilityAudioProcessorEditor::UtilityAudioProcessorEditor (UtilityAudioProcessor&
m_gainS.setSliderStyle(Slider::LinearVertical);
m_gainS.setRange(-60.0f, 20.0f, 0.1f);
m_gainS.setVelocityBasedMode(false);
m_gainS.setVelocityModeParameters(0.5, 0.1, 0.01);
m_gainS.setVelocityModeParameters(0.5, 2, 0.01);
m_gainS.setValue(*processor.p_gainS, NotificationType::dontSendNotification);
m_gainS.setDoubleClickReturnValue(true, 0.0f);
m_gainS.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
......@@ -165,7 +165,7 @@ UtilityAudioProcessorEditor::UtilityAudioProcessorEditor (UtilityAudioProcessor&
m_width.setRange(-1.0f, 1.0f, 0.01f);
m_width.setMouseCursor(MouseCursor::UpDownResizeCursor);
m_width.setVelocityBasedMode(false);
m_width.setVelocityModeParameters(0.5, 0.1, 0.01);
m_width.setVelocityModeParameters(0.5, 2, 0.01);
m_width.setValue(*processor.p_width, NotificationType::dontSendNotification);
m_width.setDoubleClickReturnValue(true, 0.0f);
m_width.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
......@@ -177,7 +177,7 @@ UtilityAudioProcessorEditor::UtilityAudioProcessorEditor (UtilityAudioProcessor&
m_highPass.setRange(20.0f, fmin(20000.0f, processor.getSampleRate() /2.0f), 1.0f);
m_highPass.setMouseCursor(MouseCursor::UpDownResizeCursor);
m_highPass.setVelocityBasedMode(false);
m_highPass.setVelocityModeParameters(0.5, 0.1, 0.01);
m_highPass.setVelocityModeParameters(0.5, 2, 0.01);
m_highPass.setValue(*processor.p_highPass, NotificationType::dontSendNotification);
m_highPass.setDoubleClickReturnValue(true, 0.5f);
m_highPass.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
......@@ -192,7 +192,7 @@ UtilityAudioProcessorEditor::UtilityAudioProcessorEditor (UtilityAudioProcessor&
m_lowPass.setRange(20.0f, fmin(20000.0f, processor.getSampleRate() / 2.0f), 1.0f);
m_lowPass.setMouseCursor(MouseCursor::UpDownResizeCursor);
m_lowPass.setVelocityBasedMode(false);
m_lowPass.setVelocityModeParameters(0.5, 0.1, 0.01);
m_lowPass.setVelocityModeParameters(0.5, 2, 0.01);
m_lowPass.setValue(*processor.p_lowPass, NotificationType::dontSendNotification);
m_lowPass.setDoubleClickReturnValue(true, 0.5f);
m_lowPass.setTextBoxStyle(Slider::NoTextBox, false, 90, 0);
......@@ -226,7 +226,7 @@ UtilityAudioProcessorEditor::UtilityAudioProcessorEditor (UtilityAudioProcessor&
lnfIn->setColour(LevelMeter::lmMeterGradientLowColour, juce::Colours::green);
lnfOut->setColour(LevelMeter::lmMeterGradientLowColour, juce::Colours::green);
meterIn = new LevelMeter(LevelMeter::MeterFlags::HasBorder);
meterIn = new LevelMeter(LevelMeter::MeterFlags::Default);
meterIn->setLookAndFeel(lnfIn);
meterIn->setMeterSource(processor.getMeterSourceIn());
meterOut = new LevelMeter(LevelMeter::MeterFlags::HasBorder);
......@@ -235,6 +235,9 @@ UtilityAudioProcessorEditor::UtilityAudioProcessorEditor (UtilityAudioProcessor&
addAndMakeVisible(meterIn);
addAndMakeVisible(meterOut);
meterIn->addListener(this);
meterOut->addListener(this);
setSize (400, 500);
}
......@@ -447,6 +450,18 @@ void UtilityAudioProcessorEditor::comboBoxChanged(ComboBox * comboBoxThatHasChan
processor.updateHostDisplay();
}
void UtilityAudioProcessorEditor::clipLightClicked(LevelMeter* meter, const int channel, juce::ModifierKeys mods)
{
if (meter == meterIn)
meterIn->clearClipIndicator();
else if (meter == meterOut)
meterOut->clearClipIndicator();
}
void UtilityAudioProcessorEditor::maxLevelClicked(LevelMeter* meter, const int channel, juce::ModifierKeys mods)
{
}
void UtilityAudioProcessorEditor::getGainDB()
{
float val = m_gain.getValue();
......
......@@ -8,7 +8,7 @@
//==============================================================================
/**
*/
class UtilityAudioProcessorEditor : public AudioProcessorEditor, private ButtonListener, private SliderListener, private ComboBoxListener
class UtilityAudioProcessorEditor : public AudioProcessorEditor, private ButtonListener, private SliderListener, private ComboBoxListener, private LevelMeter::Listener
{
public:
UtilityAudioProcessorEditor (UtilityAudioProcessor&);
......@@ -21,6 +21,8 @@ public:
void buttonClicked(juce::Button * button) override;
void sliderValueChanged(Slider* slider) override;
void comboBoxChanged(ComboBox *comboBoxThatHasChanged) override;
void clipLightClicked(LevelMeter* meter, const int channel, juce::ModifierKeys mods) override;
void maxLevelClicked(LevelMeter* meter, const int channel, juce::ModifierKeys mods) override;
Slider m_highPass;
Slider m_lowPass;
......
......@@ -109,19 +109,19 @@ void UtilityAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBloc
m_midBuffer.setSize(1, samplesPerBlock);
m_sideBuffer.setSize(1, samplesPerBlock);
m_lpf.setup(3, sampleRate, fmin(20000.0f, (sampleRate / 2.0f) - 500.0f));
m_hpf.setup(3, sampleRate, 20.0f);
*p_highPass = fmin(static_cast<float>(*p_highPass), sampleRate / 2.0f);
*p_lowPass = fmin(static_cast<float>(*p_lowPass), sampleRate / 2.0f);
m_lpf.setup(3, sampleRate, fmin((double)*p_lowPass, (sampleRate / 2.0f) - 500.0f));
m_hpf.setup(hpforder, sampleRate, fmin((double)*p_highPass, (sampleRate / 2.0f) - 500.0f));
m_sampleRate = sampleRate;
lowPassCutoff.reset(sampleRate, 0.0005);
highPassCutoff.reset(sampleRate, 0.0005);
m_prevHighPass = 0.0f;
m_prevLowPass = 0.0f;
*p_highPass = fmin(static_cast<float>(*p_highPass), sampleRate / 2.0f);
*p_lowPass = fmin(static_cast<float>(*p_lowPass), sampleRate / 2.0f);
m_prevHighPass = *p_highPass;
m_prevLowPass = *p_lowPass;
if (getActiveEditor() != nullptr)
{
......@@ -173,7 +173,7 @@ void UtilityAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer&
{
highPassCutoff.setValue(*p_highPass);
float newVal = highPassCutoff.getNextValue();
m_hpf.setup(3, m_sampleRate, fmin(newVal, ((m_sampleRate / 2.0f) - 500.0f)));
m_hpf.setup(hpforder, m_sampleRate, fmin(newVal, ((m_sampleRate / 2.0f) - 500.0f)));
m_prevHighPass = newVal;
}
......@@ -204,18 +204,6 @@ void UtilityAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer&
float instantGainL = *p_phaseL ? -1.0f : 1.0f;
float instantGainR = *p_phaseR ? -1.0f : 1.0f;
instantGainL *= *p_muteL ? 0.0f : 1.0f;
instantGainR *= *p_muteR ? 0.0f : 1.0f;
if (*p_pad)
{
instantGainL *= 0.1f;
instantGainR *= 0.1f;
}
buffer.applyGain(0, 0, numSamples, instantGainL);
buffer.applyGain(1, 0, numSamples, instantGainR);
midSideProcess(buffer);
if (*p_pan != 0.5f)
......@@ -250,6 +238,18 @@ void UtilityAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer&
if (*p_lpfOn)
m_lpf.process(numSamples, buffer.getArrayOfWritePointers());
instantGainL *= *p_muteL ? 0.0f : 1.0f;
instantGainR *= *p_muteR ? 0.0f : 1.0f;
if (*p_pad)
{
instantGainL *= 0.1f;
instantGainR *= 0.1f;
}
buffer.applyGain(0, 0, numSamples, instantGainL);
buffer.applyGain(1, 0, numSamples, instantGainR);
if (*p_hardClip || *p_softClip)
clipSamples(buffer);
......@@ -270,15 +270,62 @@ AudioProcessorEditor* UtilityAudioProcessor::createEditor()
//==============================================================================
void UtilityAudioProcessor::getStateInformation (MemoryBlock& destData)
{
// You should use this method to store your parameters in the memory block.
// You could do that either as raw data, or use the XML or ValueTree classes
// as intermediaries to make it easy to save and load complex data.
ScopedPointer<XmlElement> xml(new XmlElement("PluginSettings"));
xml->setAttribute("p_input", (int)*p_input);
xml->setAttribute("p_mute", (bool)*p_mute);
xml->setAttribute("p_pad", (bool)*p_pad);
xml->setAttribute("p_DCoffset", (bool)*p_DCoffset);
xml->setAttribute("p_gain", (double)*p_gain);
xml->setAttribute("p_pan", (double)*p_pan);
xml->setAttribute("p_gainL", (double)*p_gainL);
xml->setAttribute("p_gainR", (double)*p_gainR);
xml->setAttribute("p_phaseL", (bool)*p_phaseL);
xml->setAttribute("p_phaseR", (bool)*p_phaseR);
xml->setAttribute("p_muteL", (bool)*p_phaseL);
xml->setAttribute("p_muteR", (bool)*p_muteR);
xml->setAttribute("p_gainM", (double)*p_gainM);
xml->setAttribute("p_gainS", (double)*p_gainS);
xml->setAttribute("p_width", (double)*p_width);
xml->setAttribute("p_muteM", (bool)*p_muteS);
xml->setAttribute("p_lowPass", (double)*p_lowPass);
xml->setAttribute("p_highPass", (double)*p_highPass);
xml->setAttribute("p_hpfOn", (bool)*p_hpfOn);
xml->setAttribute("p_lpfOn", (bool)*p_lpfOn);
xml->setAttribute("p_hardClip", (bool)*p_hardClip);
xml->setAttribute("p_softClip", (bool)*p_softClip);
copyXmlToBinary(*xml, destData);
}
void UtilityAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
// You should use this method to restore your parameters from this memory block,
// whose contents will have been created by the getStateInformation() call.
ScopedPointer<XmlElement> xmlState(getXmlFromBinary(data, sizeInBytes));
if (xmlState != nullptr)
if (xmlState->hasTagName("PluginSettings"))
{
*p_input = xmlState->getIntAttribute("p_input", 1);
*p_mute = xmlState->getBoolAttribute("p_mute", false);
*p_pad = xmlState->getBoolAttribute("p_pad", false);
*p_DCoffset = xmlState->getBoolAttribute("p_DCoffset", false);
*p_gain = xmlState->getDoubleAttribute("p_gain", 1.0f);
*p_pan = xmlState->getDoubleAttribute("p_pan", 0.5f);
*p_gainL = xmlState->getDoubleAttribute("p_gainL", 1.0f);
*p_gainR = xmlState->getDoubleAttribute("p_gainR", 1.0f);
*p_phaseL = xmlState->getBoolAttribute("p_phaseL", false);
*p_phaseR = xmlState->getBoolAttribute("p_phaseR", false);
*p_muteL = xmlState->getBoolAttribute("p_muteL", false);
*p_muteR = xmlState->getBoolAttribute("p_muteR", false);
*p_gainM = xmlState->getDoubleAttribute("p_gainM", 1.0f);
*p_gainS = xmlState->getDoubleAttribute("p_gainS", 1.0f);
*p_width = xmlState->getDoubleAttribute("p_width", 0.0f);
*p_muteM = xmlState->getBoolAttribute("p_muteM", false);
*p_muteS = xmlState->getBoolAttribute("p_muteS", false);
*p_lowPass = xmlState->getDoubleAttribute("p_lowPass", 20000.0f);
*p_highPass = xmlState->getDoubleAttribute("p_highPass", 20.0f);
*p_hpfOn = xmlState->getBoolAttribute("p_hpfOn", false);
*p_lpfOn = xmlState->getBoolAttribute("p_lpfOn", false);
*p_hardClip = xmlState->getBoolAttribute("p_hardClip", false);
*p_hardClip = xmlState->getBoolAttribute("p_softClip", false);
}
}
//==============================================================================
......
......@@ -3,6 +3,7 @@
#include "../JuceLibraryCode/JuceHeader.h"
#include "DspFilters/Dsp.h"
#define HPFORDER 4
//==============================================================================
/**
......@@ -102,12 +103,12 @@ private:
AudioSampleBuffer m_sideBuffer;
Dsp::SimpleFilter <Dsp::Butterworth::LowPass <3>, 2> m_lpf;
Dsp::SimpleFilter <Dsp::Butterworth::HighPass <3>, 2> m_hpf;
Dsp::SimpleFilter <Dsp::Butterworth::HighPass <HPFORDER>, 2> m_hpf;
float m_prevLowPass = 20000.0f;
float m_prevHighPass = 0.0f;
float m_sampleRate = 44100.0f;
double m_sampleRate = 44100.0f;
LinearSmoothedValue<float> lowPassCutoff;
LinearSmoothedValue<float> highPassCutoff;
......@@ -121,6 +122,8 @@ private:
LevelMeterSource meterSourceIn;
LevelMeterSource meterSourceOut;
const int hpforder = HPFORDER;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UtilityAudioProcessor)
};
......
......@@ -34,7 +34,7 @@ or set it only to the meters, if you don't want it to interfere.
// adjust the colours to how you like them
lnf->setColour (LevelMeter::lmMeterGradientLowColour, juce::Colours::green);
meter = new LevelMeter (LevelMeter::VerticalMeters);
meter = new LevelMeter (); // See LevelMeter::MeterFlags for options
meter->setLookAndFeel (lnf);
meter->setMeterSource (processor.getMeterSource());
addAndMakeVisible (meter);
......
......@@ -152,14 +152,14 @@ void LevelMeter::mouseDown (const juce::MouseEvent &event)
innerBounds,
source);
if (hit >= 0) {
listeners.call (&LevelMeter::Listener::clipLightClicked, hit);
listeners.call (&LevelMeter::Listener::clipLightClicked, this, hit, event.mods);
}
hit = lnf->hitTestMaxNumber (event.getPosition(),
meterType,
innerBounds,
source);
if (hit >= 0) {
listeners.call (&LevelMeter::Listener::maxLevelClicked, hit);
listeners.call (&LevelMeter::Listener::maxLevelClicked, this, hit, event.mods);
}
}
}
......
......@@ -33,12 +33,13 @@
==============================================================================
*/
#ifndef LEVELMETER_H_INCLUDED
#define LEVELMETER_H_INCLUDED
#pragma once
//==============================================================================
/*
\class LevelMeter
\brief A component to display live gain and RMS readings
This class is used to display a level reading. It supports max and RMS levels.
You can also set a reduction value to display, the definition of that value is up to you.
*/
......@@ -47,35 +48,40 @@ class LevelMeter : public juce::Component, private juce::Timer
public:
enum MeterFlags {
Default = 0x0000,
Horizontal = 0x0001,
Vintage = 0x0002,
SingleChannel = 0x0004,
HasBorder = 0x0008,
Reduction = 0x0010,
Minimal = 0x0020
Default = 0x0000, /**< Default is showing all channels in the LevelMeterSource without a border */
Horizontal = 0x0001, /**< Displays the level bars horizontally */
Vintage = 0x0002, /**< Switches to a special mode of old school meters (to come) */
SingleChannel = 0x0004, /**< Display only one channel meter. \see setSelectedChannel */
HasBorder = 0x0008, /**< Displays a rounded border around the meter. This is used with the default constructor */
Reduction = 0x0010, /**< Add a reduction meter to be displayed within the meter bar. The value can be set in the LevelMeterSource, \see LevelMeterSource::setReductionLevel (currently unavailable) */
Minimal = 0x0020 /**< For a stereo meter, this tries to save space by showing only one line tickmarks in the middle and no max numbers */
};
enum ColourIds {
lmTextColour = 0x2200001,
lmTextDeactiveColour,
lmTextClipColour,
lmTicksColour,
lmOutlineColour,
lmBackgroundColour,
lmBackgroundClipColour,
lmMeterForegroundColour,
lmMeterOutlineColour,
lmMeterBackgroundColour,
lmMeterMaxNormalColour,
lmMeterMaxWarnColour,
lmMeterMaxOverColour,
lmMeterGradientLowColour,
lmMeterGradientMidColour,
lmMeterGradientMaxColour,
lmMeterReductionColour
lmTextColour = 0x2200001, /**< Colour for the numbers etc. */
lmTextDeactiveColour, /**< Unused, will eventually be removed */
lmTextClipColour, /**< Colour to print the max number if it has clipped */
lmTicksColour, /**< Colour for the tick marks */
lmOutlineColour, /**< Colour for the frame around all */
lmBackgroundColour, /**< Background colour */
lmBackgroundClipColour, /**< This is the colour of the clip indicator if it has clipped */
lmMeterForegroundColour, /**< Unused, will eventually be removed */
lmMeterOutlineColour, /**< Colour for the outlines of meter bars etc. */
lmMeterBackgroundColour, /**< Background colour for the actual meter bar and the max number */
lmMeterMaxNormalColour, /**< Text colour for the max number, if under warn threshold */
lmMeterMaxWarnColour, /**< Text colour for the max number, if between warn threshold and clip threshold */
lmMeterMaxOverColour, /**< Text colour for the max number, if above the clip threshold */
lmMeterGradientLowColour, /**< Colour for the meter bar under the warn threshold */
lmMeterGradientMidColour, /**< Colour for the meter bar in the warn area */
lmMeterGradientMaxColour, /**< Colour for the meter bar at the clip threshold */
lmMeterReductionColour /**< Colour for the reduction meter displayed within the meter */
};
/**
These methods define a interface for the LookAndFeel class of juce.
The LevelMeter needs a LookAndFeel, that implements these methods.
There is a default implementation to be included in your custom LookAndFeel class, \see LookAndFeelMethods.h
*/
class LookAndFeelMethods {
public:
virtual ~LookAndFeelMethods() {}
......@@ -204,23 +210,62 @@ public:
void timerCallback () override;
/**
Set a LevelMeterSource to display. This separation is used, so the source can work in the processing and the
GUI can display the values.
*/
void setMeterSource (LevelMeterSource* source);
/**
Set a specific channel to display. This is only useful, if MeterFlags::SingleChannel is set.
*/
void setSelectedChannel (const int c);
void setRefreshRateHz (const int newRefreshRate);
/**
Unset the clip indicator flag for a channel. Use -1 to reset all clip indicators.
*/
void clearClipIndicator (const int channel=-1);
/**
Set the max level display back to -inf for a channel. Use -1 to reset all max levels.
*/
void clearMaxLevelDisplay (const int channel=-1);
void mouseDown (const juce::MouseEvent& event) override;
/**
This Listener interface is meant to implement behaviour if either the clip indicator or the max level text
is clicked.
An example implementation could look like this (+alt means clear all, else clear the clicked number):
\code{.cpp}
void clipLightClicked (LevelMeter* clickedMeter, const int channel, ModifierKeys mods) override
{
clickedMeter->clearClipIndicator (mods.isAltDown() ? -1 : channel);
}
void maxLevelClicked (LevelMeter* clickedMeter, const int channel, ModifierKeys mods) override
{
clickedMeter->clearMaxLevelDisplay (mods.isAltDown() ? -1 : channel);
}
\endcode
*/
class Listener {
public:
virtual ~Listener () {}
virtual void clipLightClicked (const int channel) = 0;
virtual void maxLevelClicked (const int channel) = 0;
/**
This is called, when the user clicks a clip indicator. It can be used to reset the clip indicator.
To allow different behaviour, e.g. resetting only one indicator or even all meters spread over the UI.
\see clearClipIndicator, maxLevelClicked
*/
virtual void clipLightClicked (LevelMeter* meter, const int channel, juce::ModifierKeys mods) = 0;
/**
This is called, when the user clicks a max level text. It can be used to reset the max number.
\see clearMaxLevelDisplay, clipLightClicked
*/
virtual void maxLevelClicked (LevelMeter* meter, const int channel, juce::ModifierKeys mods) = 0;
};
void addListener (Listener*);
......@@ -249,5 +294,3 @@ private:
inline LevelMeter::MeterFlags operator|(LevelMeter::MeterFlags a, LevelMeter::MeterFlags b)
{return static_cast<LevelMeter::MeterFlags>(static_cast<int>(a) | static_cast<int>(b));}
#endif // LEVELMETER_H_INCLUDED
......@@ -101,7 +101,7 @@ private:
pushNextRMS (newRms);
}
void setRMSsize (const int numBlocks) {
rmsHistory.resize (numBlocks);
rmsHistory.resize (numBlocks, 0.0f);
rmsPtr %= rmsHistory.size();
}
private:
......@@ -109,9 +109,11 @@ private:
const float squaredRMS = std::min (newRMS * newRMS, 1.0f);
if (rmsHistory.size() > 0) {
float oldRMS = rmsSum - rmsHistory [rmsPtr];
if (abs(oldRMS) < 0.00001f)
oldRMS = 0.0f;
rmsSum = oldRMS + squaredRMS;
rmsHistory [rmsPtr] = squaredRMS;
rmsPtr = ++rmsPtr % rmsHistory.size();
rmsPtr = (rmsPtr + 1) % rmsHistory.size();
}
else {
rmsSum = squaredRMS;
......
......@@ -27,7 +27,7 @@
==============================================================================
ff_meters_LookAndFeel.h
\file ff_meters_LookAndFeel.h
Author: Daniel Walz
==============================================================================
......@@ -37,6 +37,26 @@
class LevelMeterSource;
/**
\class LevelMeterLookAndFeel
\brief Convenience LookAndFeel which derives from LookAndFeel_V3 and LevelMeter::LookAndFeelMethods
This is the shortcut, to get a component going without inheriting any LookAndFeel class.
If you write your own LookAndFeel, you can include ff_meters_LookAndFeelMethods.h inside your LookAndFeel:
\code{.cpp}
class MyLookAndFeel : public LookAndFeel_V4, LevelMeter::LookAndFeelMethods
{
public:
#include "ff_meters_LookAndFeelMethods.h"
// ...
};
\endcode
*/
class LevelMeterLookAndFeel : public juce::LookAndFeel_V3, public LevelMeter::LookAndFeelMethods
{
public:
......
......@@ -27,7 +27,7 @@
==============================================================================
ff_meters_LookAndFeelMethods.h
\file ff_meters_LookAndFeelMethods.h
Author: Daniel Walz
To use the default implementation of your LevelMeter in your LookAndFeel,
......@@ -537,7 +537,7 @@ void drawTickMarks (juce::Graphics& g,
bounds.getBottom() - 4);
}
else {
const float h = (bounds.getHeight() - 2.0) * 0.1;
const float h = (bounds.getHeight() - 2.0) * 0.05;
g.setFont (h * 0.8f);
for (int i=0; i<11; ++i) {
const float y = bounds.getY() + i * h;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment