Commit 6c90498b authored by Jonathan Hyde's avatar Jonathan Hyde

Multiple changes:

New left + right input pan knobs, or a pre mono pan balance when set to dual mono
Filter automation is now logarithmic
Fixed speed of filter inconsistent with different buffer sizes
New about window
parent f791c431
#ifndef ABOUTWINDOW_H_INCLUDED
#define ABOUTWINDOW_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
//==============================================================================
/*
*/
class AboutWindow : public Component, private ButtonListener
{
public:
Label aboutText;
HyperlinkButton vennLink;
TextButton close;
Image vlogosmall;
URL donate;
ImageButton donateButton;
Image donateImg;
AboutWindow()
{
donate = URL("https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=TYKD59N6ZFHP6");
vlogosmall = ImageCache::getFromMemory(BinaryData::logosmall_png, BinaryData::logosmall_pngSize);
donateImg = ImageCache::getFromMemory(BinaryData::donate_png, BinaryData::donate_pngSize);
String text;
text << "Utility\n" << "Version: " << JucePlugin_VersionString << "\nProvided by: Venn Audio\nDeveloped by: Jonathan Hyde\nLicense: GNU GPL v3";
aboutText.setText(text, NotificationType::dontSendNotification);
aboutText.setFont(12.0f);
aboutText.setJustificationType(Justification::topLeft);
vennLink.setURL(URL("http://www.vennaudio.com"));
vennLink.setButtonText("www.vennaudio.com");
vennLink.setFont(Font("Arial", 14.0f, 0), false, Justification::left);
close.setButtonText("Okay!");
close.addListener(this);
donateButton.setImages(true, true, true, donateImg, 1.0f, Colours::transparentBlack, Image(), 0.9f, Colours::transparentBlack, Image(), 0.5f, Colours::transparentBlack);
donateButton.addListener(this);
addAndMakeVisible(&aboutText);
addAndMakeVisible(&vennLink);
addAndMakeVisible(&close);
addAndMakeVisible(&donateButton);
}
~AboutWindow()
{
}
void paint (Graphics& g) override
{
g.fillAll (Colours::white);
g.setColour (Colours::grey);
g.drawRect (getLocalBounds(), 1);
g.drawImage(vlogosmall, 25, 100, vlogosmall.getWidth(), vlogosmall.getHeight(), 0, 0, vlogosmall.getWidth(), vlogosmall.getHeight());
}
void resized() override
{
aboutText.setBounds(10, 10, getWidth() - 10, 65);
vennLink.setBounds(15, 75, getWidth() - 15, 10);
close.setBounds(getWidth() - 65, getHeight() - 15 - donateButton.getHeight() + 2, 50, donateButton.getHeight() - 4);
donateButton.setBounds(15, getHeight() - 15 - donateButton.getHeight(), donateButton.getWidth(), donateButton.getHeight());
}
void buttonClicked(juce::Button * button) override
{
if (button == &close)
this->setVisible(false);
else if (button == &donateButton)
donate.launchInDefaultBrowser();
}
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AboutWindow)
};
#endif // ABOUTWINDOW_H_INCLUDED
This diff is collapsed.
......@@ -265,4 +265,38 @@ class OtherLookAndFeel4 : public LookAndFeel_V3
}
}
};
class MyLevelMeterLookAndFeel : public LookAndFeel_V3, FFAU::LevelMeter::LookAndFeelMethods
{
public:
juce::Rectangle<float> getMeterMaxNumberBounds(const juce::Rectangle<float> bounds,
const FFAU::LevelMeter::MeterFlags meterType) const override
{
if (meterType & FFAU::LevelMeter::Minimal) {
return juce::Rectangle<float>();
}
else if (meterType & FFAU::LevelMeter::Vintage) {
return bounds;
}
else {
if (meterType & FFAU::LevelMeter::Horizontal) {
const float margin = bounds.getHeight() * 0.05;
return juce::Rectangle<float>(bounds.getX() + margin,
bounds.getCentreY() + margin,
60,
bounds.getHeight() * 0.5 - margin * 2.0);
}
else {
const float margin = bounds.getWidth() * 0.05;
return juce::Rectangle<float>(bounds.getX() + margin,
bounds.getBottom() - (margin + 25),
bounds.getWidth() - 2 * margin,
25.0);
}
}
}
};
#endif // OTHERLOOKANDFEEL_H_INCLUDED
This diff is collapsed.
......@@ -4,11 +4,12 @@
#include "../JuceLibraryCode/JuceHeader.h"
#include "PluginProcessor.h"
#include "OtherLookAndFeel.h"
#include "AboutWindow.h"
//==============================================================================
/**
*/
class UtilityAudioProcessorEditor : public AudioProcessorEditor, private ButtonListener, private SliderListener, private ComboBoxListener, private LevelMeter::Listener, private Timer
class UtilityAudioProcessorEditor : public AudioProcessorEditor, private ButtonListener, private SliderListener, private ComboBoxListener, private FFAU::LevelMeter::Listener, private Timer
{
public:
UtilityAudioProcessorEditor (UtilityAudioProcessor&);
......@@ -21,8 +22,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;
void clipLightClicked(FFAU::LevelMeter* meter, const int channel, juce::ModifierKeys mods) override;
void maxLevelClicked(FFAU::LevelMeter* meter, const int channel, juce::ModifierKeys mods) override;
Slider m_highPass;
Slider m_lowPass;
......@@ -48,6 +49,9 @@ private:
TextButton m_hardClip;
TextButton m_softClip;
Slider m_panL;
Slider m_panR;
Slider m_prePan;
Slider m_gain;
Slider m_pan;
Slider m_gainL;
......@@ -63,11 +67,14 @@ private:
OtherLookAndFeel3 otherLookAndFeel3;
OtherLookAndFeel4 otherLookAndFeel4;
ScopedPointer<LevelMeter> meterIn;
ScopedPointer<LevelMeter> meterOut;
ScopedPointer<LevelMeterLookAndFeel> lnfIn;
ScopedPointer<LevelMeterLookAndFeel> lnfOut;
ScopedPointer<FFAU::LevelMeter> meterIn;
ScopedPointer<FFAU::LevelMeter> meterOut;
ScopedPointer<FFAU::LevelMeterLookAndFeel> lnfIn;
ScopedPointer<FFAU::LevelMeterLookAndFeel> lnfOut;
Label m_lpanL;
Label m_lpanR;
Label m_lprePan;
Label m_lgainDB;
Label m_lPan;
Label m_lWidth;
......@@ -76,9 +83,18 @@ private:
void getGainDB();
void getPanText();
void getLPanText();
void getRPanText();
void getPrePanText();
void getWidthText();
int horShift = 100;
int vertShift = 65;
Image vlogo;
ScopedPointer<AboutWindow> aboutWindow;
TextButton aboutButton;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UtilityAudioProcessorEditor)
};
......
This diff is collapsed.
......@@ -8,11 +8,31 @@
#include <ATK/Core/OutPointerFilter.h>
#include <ATK/Core/PipelineGlobalSinkFilter.h>
#define HPFORDER 3
#define HPFORDER 2
//==============================================================================
/**
*/
class ValueSmoother
{
public:
ValueSmoother();
~ValueSmoother();
void reset(double sampleRate, int samplesPerBlock, double initValue, double time);
void setTarget(double target);
float getNextValue();
float getTarget();
private:
float m_currentValue;
float m_target;
float m_interval;
double m_sampleRate;
double m_time;
int m_samplesPerBlock;
};
class UtilityAudioProcessor : public AudioProcessor
{
public:
......@@ -52,6 +72,10 @@ public:
void getStateInformation (MemoryBlock& destData) override;
void setStateInformation (const void* data, int sizeInBytes) override;
AudioParameterFloat *p_panL;
AudioParameterFloat *p_panR;
AudioParameterFloat *p_prePan;
AudioParameterInt *p_input;
AudioParameterBool *p_mute;
AudioParameterBool *p_pad;
......@@ -82,17 +106,30 @@ public:
AudioParameterBool *p_hardClip;
AudioParameterBool *p_softClip;
LevelMeterSource* getMeterSourceIn()
FFAU::LevelMeterSource* getMeterSourceIn()
{
return &meterSourceIn;
}
LevelMeterSource* getMeterSourceOut()
FFAU::LevelMeterSource* getMeterSourceOut()
{
return &meterSourceOut;
}
double getFreq(float value);
private:
//==============================================================================
float m_prevPanL = 0.0f;
float m_prevPanR = 1.0f;
float l_prevRampGainL = 1.0f;
float l_prevRampGainR = 0.0f;
float r_prevRampGainL = 0.0f;
float r_prevRampGainR = 1.0f;
float m_prevPrePan = 0.5f;
float m_prevPreGainL = 0.5f;
float m_prevPreGainR = 0.5f;
float m_gainF = 1.0f;
float m_gainLF = 1.0f;
float m_gainRF = 1.0f;
......@@ -115,17 +152,19 @@ private:
void midSideProcess(AudioSampleBuffer &buffer);
void clipSamples(AudioSampleBuffer &buffer);
void dcOffset(AudioSampleBuffer &buffer);
void channelPans(AudioSampleBuffer &buffer);
AudioSampleBuffer m_midBuffer;
AudioSampleBuffer m_sideBuffer;
AudioSampleBuffer m_tempBuffer;
float m_prevLowPass = 20000.0f;
float m_prevHighPass = 0.0f;
float m_prevLowPass = 0.0;
float m_prevHighPass = 100.0;
double m_sampleRate = 44100.0f;
LinearSmoothedValue<float> lowPassCutoff;
LinearSmoothedValue<float> highPassCutoff;
ValueSmoother m_lowPassSmoother;
ValueSmoother m_highPassSmoother;
double m_prevInL = 0.0f;
double m_prevOutL = 0.0f;
......@@ -133,11 +172,13 @@ private:
double m_prevOutR = 0.0f;
double m_eps;
LevelMeterSource meterSourceIn;
LevelMeterSource meterSourceOut;
FFAU::LevelMeterSource meterSourceIn;
FFAU::LevelMeterSource meterSourceOut;
const int hpforder = HPFORDER;
bool m_monoSet;
ATK::InPointerFilter<float> inFilterL;
ATK::InPointerFilter<float> inFilterL2;
ATK::InPointerFilter<float> inFilterR;
......@@ -157,5 +198,4 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UtilityAudioProcessor)
};
#endif // PLUGINPROCESSOR_H_INCLUDED
......@@ -654,6 +654,8 @@ FILE_PATTERNS =
RECURSIVE = YES
USE_MDFILE_AS_MAINPAGE = README.md
# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
......
......@@ -27,26 +27,29 @@ Or you can use the LevelMeterLookAndFeel directly because it inherits from juce:
for your convenience. You can set it as default LookAndFeel, if you used the default,
or set it only to the meters, if you don't want it to interfere.
All classes are in the namespace FFAU to avoid collisions. You can either prefix each symbol,
or import the namespace.
// In your Editor
public:
PluginEditor () {
lnf = new LevelMeterLookAndFeel();
lnf = new FFAU::LevelMeterLookAndFeel();
// adjust the colours to how you like them
lnf->setColour (LevelMeter::lmMeterGradientLowColour, juce::Colours::green);
lnf->setColour (FFAU::LevelMeter::lmMeterGradientLowColour, juce::Colours::green);
meter = new LevelMeter (); // See LevelMeter::MeterFlags for options
meter = new FFAU::LevelMeter (); // See FFAU::LevelMeter::MeterFlags for options
meter->setLookAndFeel (lnf);
meter->setMeterSource (processor.getMeterSource());
addAndMakeVisible (meter);
// ...
}
private:
ScopedPointer<LevelMeter> meter;
ScopedPointer<LevelMeterLookAndFeel> lnf;
ScopedPointer<FFAU::LevelMeter> meter;
ScopedPointer<FFAU::LevelMeterLookAndFeel> lnf;
// and in the processor:
public:
LevelMeterSource* getMeterSource ()
FFAU::LevelMeterSource* getMeterSource ()
{
return &meterSource;
}
......@@ -58,7 +61,7 @@ or set it only to the meters, if you don't want it to interfere.
}
private:
LevelMeterSource meterSource;
FFAU::LevelMeterSource meterSource;
......
......@@ -32,35 +32,37 @@
vendor: Foleys Finest Audio UG / Filmstro Ltd.
version: 0.9.0
name: Meters with GUI and LookAndFeel
description: Audio helper classes of general purpose
dependencies: juce_audio_basics, juce_audio_formats, juce_audio_devices, juce_audio_processors
description: Contains a metering Component, that can display live peak and RMS values
dependencies: juce_audio_basics, juce_gui_basics, juce_events
website: http://www.foleysfinest.com/
license: BSD V2 3-clause
END_JUCE_MODULE_DECLARATION
==============================================================================
@defgroup ff_meters
This module provides a display component to show RMS, MAX and CLIP values.
There is a MeterInputSource, which can process any AudioBuffer, and provide
therefore the data for live display.
==============================================================================
*/
#ifndef FF_AUDIO_METERS_INCLUDED_H
#define FF_AUDIO_METERS_INCLUDED_H
#pragma once
#ifndef USE_FF_AUDIO_METERS
#define USE_FF_AUDIO_METERS 1
#endif
#include <juce_audio_basics/juce_audio_basics.h>
#include <juce_audio_formats/juce_audio_formats.h>
#include <juce_audio_processors/juce_audio_processors.h>
#include <juce_audio_devices/juce_audio_devices.h>
#include <juce_gui_basics/juce_gui_basics.h>
#include <juce_events/juce_events.h>
#include <ff_meters/ff_meters_LevelMeterSource.h>
//#include <ff_meters/ff_meters_LookAndFeelVertical.h>
//#include <ff_meters/ff_meters_LookAndFeelHorizontal.h>
//#include <ff_meters/ff_meters_LookAndFeelVintage.h>
#include <ff_meters/ff_meters_LevelMeter.h>
#include <ff_meters/ff_meters_LookAndFeel.h>
#endif /* FF_AUDIO_METERS_INCLUDED_H */
......@@ -38,9 +38,10 @@
//==============================================================================
LevelMeter::LevelMeter (const MeterFlags type)
FFAU::LevelMeter::LevelMeter (const MeterFlags type)
: source (nullptr),
selectedChannel (-1),
fixedNumChannels(-1),
meterType (type),
refreshRate (30),
useBackgroundImage (false),
......@@ -49,34 +50,46 @@ LevelMeter::LevelMeter (const MeterFlags type)
startTimerHz (refreshRate);
}
LevelMeter::~LevelMeter()
FFAU::LevelMeter::~LevelMeter()
{
stopTimer();
}
void LevelMeter::setMeterSource (LevelMeterSource* src)
void FFAU::LevelMeter::setMeterFlags (const MeterFlags type)
{
meterType = type;
}
void FFAU::LevelMeter::setMeterSource (LevelMeterSource* src)
{
source = src;
}
void LevelMeter::setSelectedChannel (const int c)
void FFAU::LevelMeter::setSelectedChannel (const int c)
{
selectedChannel = c;
}
void LevelMeter::setRefreshRateHz (const int newRefreshRate)
void FFAU::LevelMeter::setFixedNumChannels (const int numChannels)
{
fixedNumChannels = numChannels;
}
void FFAU::LevelMeter::setRefreshRateHz (const int newRefreshRate)
{
refreshRate = newRefreshRate;
startTimerHz (refreshRate);
}
void LevelMeter::paint (Graphics& g)
void FFAU::LevelMeter::paint (Graphics& g)
{
Graphics::ScopedSaveState saved (g);
LookAndFeel& l = getLookAndFeel();
if (LookAndFeelMethods* lnf = dynamic_cast<LookAndFeelMethods*> (&l)) {
const juce::Rectangle<float> bounds = getLocalBounds().toFloat();
int numChannels = source ? source->getNumChannels() : 1;
if (useBackgroundImage) {
// This seems to only speed up, if you use complex drawings on the background. For
// "normal" vector graphics the image approach seems actually slower
......@@ -84,16 +97,16 @@ void LevelMeter::paint (Graphics& g)
backgroundImage = Image (Image::ARGB, getWidth(), getHeight(), true);
Graphics backGraphics (backgroundImage);
lnf->drawBackground (backGraphics, meterType, bounds);
lnf->drawMeterBarsBackground (backGraphics, meterType, bounds, source ? source->getNumChannels() : 1);
lnf->drawMeterBarsBackground (backGraphics, meterType, bounds, numChannels, fixedNumChannels);
backgroundNeedsRepaint = false;
}
g.drawImageAt (backgroundImage, 0, 0);
lnf->drawMeterBars (g, meterType, bounds, source, selectedChannel);
lnf->drawMeterBars (g, meterType, bounds, source, fixedNumChannels, selectedChannel);
}
else {
lnf->drawBackground (g, meterType, bounds);
lnf->drawMeterBarsBackground (g, meterType, bounds, source ? source->getNumChannels() : 1);
lnf->drawMeterBars (g, meterType, bounds, source, selectedChannel);
lnf->drawMeterBarsBackground (g, meterType, bounds, numChannels, fixedNumChannels);
lnf->drawMeterBars (g, meterType, bounds, source, fixedNumChannels, selectedChannel);
}
}
else {
......@@ -105,19 +118,22 @@ void LevelMeter::paint (Graphics& g)
// LevelMeter::LookAndFeelMethods
jassertfalse;
}
if (source)
source->decayIfNeeded();
}
void LevelMeter::resized ()
void FFAU::LevelMeter::resized ()
{
backgroundNeedsRepaint = true;
}
void LevelMeter::timerCallback ()
void FFAU::LevelMeter::timerCallback ()
{
repaint();
}
void LevelMeter::clearClipIndicator (const int channel)
void FFAU::LevelMeter::clearClipIndicator (const int channel)
{
if (source) {
if (channel < 0) {
......@@ -129,7 +145,7 @@ void LevelMeter::clearClipIndicator (const int channel)
}
}
void LevelMeter::clearMaxLevelDisplay (const int channel)
void FFAU::LevelMeter::clearMaxLevelDisplay (const int channel)
{
if (source) {
if (channel < 0) {
......@@ -141,7 +157,7 @@ void LevelMeter::clearMaxLevelDisplay (const int channel)
}
}
void LevelMeter::mouseDown (const juce::MouseEvent &event)
void FFAU::LevelMeter::mouseDown (const juce::MouseEvent &event)
{
if (LookAndFeelMethods* lnf = dynamic_cast<LookAndFeelMethods*> (&getLookAndFeel())) {
const juce::Rectangle<float> innerBounds = lnf->getMeterInnerBounds (getLocalBounds().toFloat(),
......@@ -165,12 +181,12 @@ void LevelMeter::mouseDown (const juce::MouseEvent &event)
}
}
void LevelMeter::addListener (LevelMeter::Listener* listener)
void FFAU::LevelMeter::addListener (FFAU::LevelMeter::Listener* listener)
{
listeners.add (listener);
}
void LevelMeter::removeListener (LevelMeter::Listener* listener)
void FFAU::LevelMeter::removeListener (FFAU::LevelMeter::Listener* listener)
{
listeners.remove (listener);
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -34,40 +34,46 @@
*/
#pragma once
namespace FFAU
{
class LevelMeterSource;
class LevelMeterSource;
/** @addtogroup ff_meters */
/*@{*/
/**
\class LevelMeterLookAndFeel
\brief Convenience LookAndFeel which derives from LookAndFeel_V3 and LevelMeter::LookAndFeelMethods
/**
\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:
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:
\code{.cpp}
class MyLookAndFeel : public LookAndFeel_V4, LevelMeter::LookAndFeelMethods
{
public:
#include "ff_meters_LookAndFeelMethods.h"
#include "ff_meters_LookAndFeelMethods.h"
// ...
// ...
};
\endcode
*/
class LevelMeterLookAndFeel : public juce::LookAndFeel_V3, public LevelMeter::LookAndFeelMethods
{
public:
LevelMeterLookAndFeel ()
{
setupDefaultMeterColours();
}
};
\endcode
*/
class LevelMeterLookAndFeel : public juce::LookAndFeel_V3, public LevelMeter::LookAndFeelMethods
{
public:
LevelMeterLookAndFeel()
{
setupDefaultMeterColours();
}
virtual ~LevelMeterLookAndFeel() {}
virtual ~LevelMeterLookAndFeel() {}
// do this include inside the class to get the default implementation instead of copying it there
#include "ff_meters_LookAndFeelMethods.h"
// do this include inside the class to get the default implementation instead of copying it there
#include "ff_meters_LookAndFeelMethods.h"
};
}
};
/*@}*/
This diff is collapsed.
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