Skip to content

Commit 55b78b0

Browse files
committed
initial commit
0 parents  commit 55b78b0

File tree

190 files changed

+15944
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

190 files changed

+15944
-0
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
**/.DS_Store
2+
**/Builds
3+
**/JuceLibraryCode
4+
**/*.filtergraph
5+

Chapter Code/Chapter 10/Delay.jucer

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<JUCERPROJECT id="baUV92" name="Delay" projectType="audioplug" useAppConfig="0"
4+
addUsingNamespaceToJuceHeader="0" jucerFormatVersion="1" pluginFormats="buildAU,buildAUv3,buildStandalone,buildVST3"
5+
displaySplashScreen="0" pluginCode="Dlay" cppLanguageStandard="20">
6+
<MAINGROUP id="klP2XS" name="Delay">
7+
<GROUP id="{9B6AAD8A-A1DA-3D3C-2B9A-8DB65E27ED34}" name="Source">
8+
<FILE id="Aogs5S" name="Parameters.cpp" compile="1" resource="0" file="Source/Parameters.cpp"/>
9+
<FILE id="Bc3PFm" name="Parameters.h" compile="0" resource="0" file="Source/Parameters.h"/>
10+
<FILE id="r0sBSj" name="PluginEditor.cpp" compile="1" resource="0"
11+
file="Source/PluginEditor.cpp"/>
12+
<FILE id="jvM2im" name="PluginEditor.h" compile="0" resource="0" file="Source/PluginEditor.h"/>
13+
<FILE id="U9wlr4" name="PluginProcessor.cpp" compile="1" resource="0"
14+
file="Source/PluginProcessor.cpp"/>
15+
<FILE id="CcoJws" name="PluginProcessor.h" compile="0" resource="0"
16+
file="Source/PluginProcessor.h"/>
17+
<FILE id="WTkUQq" name="RotaryKnob.cpp" compile="1" resource="0" file="Source/RotaryKnob.cpp"/>
18+
<FILE id="bCTGrx" name="RotaryKnob.h" compile="0" resource="0" file="Source/RotaryKnob.h"/>
19+
</GROUP>
20+
</MAINGROUP>
21+
<MODULES>
22+
<MODULE id="juce_audio_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
23+
<MODULE id="juce_audio_devices" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
24+
<MODULE id="juce_audio_formats" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
25+
<MODULE id="juce_audio_plugin_client" showAllCode="1" useLocalCopy="0"
26+
useGlobalPath="1"/>
27+
<MODULE id="juce_audio_processors" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
28+
<MODULE id="juce_audio_utils" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
29+
<MODULE id="juce_core" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
30+
<MODULE id="juce_data_structures" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
31+
<MODULE id="juce_dsp" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
32+
<MODULE id="juce_events" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
33+
<MODULE id="juce_graphics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
34+
<MODULE id="juce_gui_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
35+
<MODULE id="juce_gui_extra" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
36+
</MODULES>
37+
<JUCEOPTIONS JUCE_STRICT_REFCOUNTEDPOINTER="1" JUCE_VST3_CAN_REPLACE_VST2="0"/>
38+
<EXPORTFORMATS>
39+
<VS2022 targetFolder="Builds/VisualStudio2022">
40+
<CONFIGURATIONS>
41+
<CONFIGURATION isDebug="1" name="Debug" targetName="Delay" enablePluginBinaryCopyStep="1"
42+
winWarningLevel="4"/>
43+
<CONFIGURATION isDebug="0" name="Release" targetName="Delay"/>
44+
</CONFIGURATIONS>
45+
<MODULEPATHS>
46+
<MODULEPATH id="juce_audio_basics" path="../../JUCE/modules"/>
47+
<MODULEPATH id="juce_audio_devices" path="../../JUCE/modules"/>
48+
<MODULEPATH id="juce_audio_formats" path="../../JUCE/modules"/>
49+
<MODULEPATH id="juce_audio_plugin_client" path="../../JUCE/modules"/>
50+
<MODULEPATH id="juce_audio_processors" path="../../JUCE/modules"/>
51+
<MODULEPATH id="juce_audio_utils" path="../../JUCE/modules"/>
52+
<MODULEPATH id="juce_core" path="../../JUCE/modules"/>
53+
<MODULEPATH id="juce_data_structures" path="../../JUCE/modules"/>
54+
<MODULEPATH id="juce_events" path="../../JUCE/modules"/>
55+
<MODULEPATH id="juce_graphics" path="../../JUCE/modules"/>
56+
<MODULEPATH id="juce_gui_basics" path="../../JUCE/modules"/>
57+
<MODULEPATH id="juce_gui_extra" path="../../JUCE/modules"/>
58+
<MODULEPATH id="juce_dsp" path="../../JUCE/modules"/>
59+
</MODULEPATHS>
60+
</VS2022>
61+
<XCODE_IPHONE targetFolder="Builds/iOS">
62+
<CONFIGURATIONS>
63+
<CONFIGURATION isDebug="1" name="Debug" targetName="Delay" recommendedWarnings="LLVM"/>
64+
<CONFIGURATION isDebug="0" name="Release" targetName="Delay"/>
65+
</CONFIGURATIONS>
66+
<MODULEPATHS>
67+
<MODULEPATH id="juce_audio_basics" path="../../JUCE/modules"/>
68+
<MODULEPATH id="juce_audio_devices" path="../../JUCE/modules"/>
69+
<MODULEPATH id="juce_audio_formats" path="../../JUCE/modules"/>
70+
<MODULEPATH id="juce_audio_plugin_client" path="../../JUCE/modules"/>
71+
<MODULEPATH id="juce_audio_processors" path="../../JUCE/modules"/>
72+
<MODULEPATH id="juce_audio_utils" path="../../JUCE/modules"/>
73+
<MODULEPATH id="juce_core" path="../../JUCE/modules"/>
74+
<MODULEPATH id="juce_data_structures" path="../../JUCE/modules"/>
75+
<MODULEPATH id="juce_events" path="../../JUCE/modules"/>
76+
<MODULEPATH id="juce_graphics" path="../../JUCE/modules"/>
77+
<MODULEPATH id="juce_gui_basics" path="../../JUCE/modules"/>
78+
<MODULEPATH id="juce_gui_extra" path="../../JUCE/modules"/>
79+
<MODULEPATH id="juce_dsp" path="../../JUCE/modules"/>
80+
</MODULEPATHS>
81+
</XCODE_IPHONE>
82+
<XCODE_MAC targetFolder="Builds/MacOSX">
83+
<CONFIGURATIONS>
84+
<CONFIGURATION isDebug="1" name="Debug" targetName="Delay" recommendedWarnings="LLVM"
85+
enablePluginBinaryCopyStep="1"/>
86+
<CONFIGURATION isDebug="0" name="Release" targetName="Delay"/>
87+
</CONFIGURATIONS>
88+
<MODULEPATHS>
89+
<MODULEPATH id="juce_audio_basics" path="../../JUCE/modules"/>
90+
<MODULEPATH id="juce_audio_devices" path="../../JUCE/modules"/>
91+
<MODULEPATH id="juce_audio_formats" path="../../JUCE/modules"/>
92+
<MODULEPATH id="juce_audio_plugin_client" path="../../JUCE/modules"/>
93+
<MODULEPATH id="juce_audio_processors" path="../../JUCE/modules"/>
94+
<MODULEPATH id="juce_audio_utils" path="../../JUCE/modules"/>
95+
<MODULEPATH id="juce_core" path="../../JUCE/modules"/>
96+
<MODULEPATH id="juce_data_structures" path="../../JUCE/modules"/>
97+
<MODULEPATH id="juce_events" path="../../JUCE/modules"/>
98+
<MODULEPATH id="juce_graphics" path="../../JUCE/modules"/>
99+
<MODULEPATH id="juce_gui_basics" path="../../JUCE/modules"/>
100+
<MODULEPATH id="juce_gui_extra" path="../../JUCE/modules"/>
101+
<MODULEPATH id="juce_dsp" path="../../JUCE/modules"/>
102+
</MODULEPATHS>
103+
</XCODE_MAC>
104+
</EXPORTFORMATS>
105+
</JUCERPROJECT>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#include "Parameters.h"
2+
3+
template<typename T>
4+
static void castParameter(juce::AudioProcessorValueTreeState& apvts,
5+
const juce::ParameterID& id, T& destination)
6+
{
7+
destination = dynamic_cast<T>(apvts.getParameter(id.getParamID()));
8+
jassert(destination); // parameter does not exist or wrong type
9+
}
10+
11+
static juce::String stringFromMilliseconds(float value, int)
12+
{
13+
if (value < 10.0f) {
14+
return juce::String(value, 2) + " ms";
15+
} else if (value < 100.0f) {
16+
return juce::String(value, 1) + " ms";
17+
} else if (value < 1000.0f) {
18+
return juce::String(int(value)) + " ms";
19+
} else {
20+
return juce::String(value * 0.001f, 2) + " s";
21+
}
22+
}
23+
24+
static float millisecondsFromString(const juce::String& text)
25+
{
26+
float value = text.getFloatValue();
27+
if (!text.endsWithIgnoreCase("ms")) {
28+
if (text.endsWithIgnoreCase("s") || value < Parameters::minDelayTime) {
29+
return value * 1000.0f;
30+
}
31+
}
32+
return value;
33+
}
34+
35+
static juce::String stringFromDecibels(float value, int)
36+
{
37+
return juce::String(value, 1) + " dB";
38+
}
39+
40+
static juce::String stringFromPercent(float value, int)
41+
{
42+
return juce::String(int(value)) + " %";
43+
}
44+
45+
Parameters::Parameters(juce::AudioProcessorValueTreeState& apvts)
46+
{
47+
castParameter(apvts, gainParamID, gainParam);
48+
castParameter(apvts, delayTimeParamID, delayTimeParam);
49+
castParameter(apvts, mixParamID, mixParam);
50+
}
51+
52+
juce::AudioProcessorValueTreeState::ParameterLayout Parameters::createParameterLayout()
53+
{
54+
juce::AudioProcessorValueTreeState::ParameterLayout layout;
55+
56+
layout.add(std::make_unique<juce::AudioParameterFloat>(
57+
gainParamID,
58+
"Output Gain",
59+
juce::NormalisableRange<float> { -12.0f, 12.0f },
60+
0.0f,
61+
juce::AudioParameterFloatAttributes().withStringFromValueFunction(stringFromDecibels)
62+
));
63+
64+
layout.add(std::make_unique<juce::AudioParameterFloat>(
65+
delayTimeParamID,
66+
"Delay Time",
67+
juce::NormalisableRange<float> { minDelayTime, maxDelayTime, 0.001f, 0.25f },
68+
100.0f,
69+
juce::AudioParameterFloatAttributes()
70+
.withStringFromValueFunction(stringFromMilliseconds)
71+
.withValueFromStringFunction(millisecondsFromString)
72+
));
73+
74+
layout.add(std::make_unique<juce::AudioParameterFloat>(
75+
mixParamID,
76+
"Mix",
77+
juce::NormalisableRange<float>(0.0f, 100.0f, 1.0f),
78+
100.0f,
79+
juce::AudioParameterFloatAttributes().withStringFromValueFunction(stringFromPercent)
80+
));
81+
82+
return layout;
83+
}
84+
85+
void Parameters::prepareToPlay(double sampleRate) noexcept
86+
{
87+
double duration = 0.02;
88+
gainSmoother.reset(sampleRate, duration);
89+
90+
coeff = 1.0f - std::exp(-1.0f / (0.2f * float(sampleRate)));
91+
92+
mixSmoother.reset(sampleRate, duration);
93+
}
94+
95+
void Parameters::reset() noexcept
96+
{
97+
gain = 0.0f;
98+
gainSmoother.setCurrentAndTargetValue(juce::Decibels::decibelsToGain(gainParam->get()));
99+
100+
delayTime = 0.0f;
101+
102+
mix = 1.0f;
103+
mixSmoother.setCurrentAndTargetValue(mixParam->get() * 0.01f);
104+
}
105+
106+
void Parameters::update() noexcept
107+
{
108+
gainSmoother.setTargetValue(juce::Decibels::decibelsToGain(gainParam->get()));
109+
110+
targetDelayTime = delayTimeParam->get();
111+
if (delayTime == 0.0f) {
112+
delayTime = targetDelayTime;
113+
}
114+
115+
mixSmoother.setTargetValue(mixParam->get() * 0.01f);
116+
}
117+
118+
void Parameters::smoothen() noexcept
119+
{
120+
gain = gainSmoother.getNextValue();
121+
122+
delayTime += (targetDelayTime - delayTime) * coeff;
123+
124+
mix = mixSmoother.getNextValue();
125+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#pragma once
2+
3+
#include <JuceHeader.h>
4+
5+
const juce::ParameterID gainParamID { "gain", 1 };
6+
const juce::ParameterID delayTimeParamID { "delayTime", 1 };
7+
const juce::ParameterID mixParamID { "mix", 1 };
8+
9+
class Parameters
10+
{
11+
public:
12+
Parameters(juce::AudioProcessorValueTreeState& apvts);
13+
14+
static juce::AudioProcessorValueTreeState::ParameterLayout createParameterLayout();
15+
16+
void prepareToPlay(double sampleRate) noexcept;
17+
void reset() noexcept;
18+
void update() noexcept;
19+
void smoothen() noexcept;
20+
21+
float gain = 0.0f;
22+
float delayTime = 0.0f;
23+
float mix = 1.0f;
24+
25+
static constexpr float minDelayTime = 5.0f;
26+
static constexpr float maxDelayTime = 5000.0f;
27+
28+
private:
29+
juce::AudioParameterFloat* gainParam;
30+
juce::LinearSmoothedValue<float> gainSmoother;
31+
32+
juce::AudioParameterFloat* delayTimeParam;
33+
34+
float targetDelayTime = 0.0f;
35+
float coeff = 0.0f; // one-pole smoothing
36+
37+
juce::AudioParameterFloat* mixParam;
38+
juce::LinearSmoothedValue<float> mixSmoother;
39+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
==============================================================================
3+
4+
This file contains the basic framework code for a JUCE plugin editor.
5+
6+
==============================================================================
7+
*/
8+
9+
#include "PluginProcessor.h"
10+
#include "PluginEditor.h"
11+
12+
//==============================================================================
13+
DelayAudioProcessorEditor::DelayAudioProcessorEditor (DelayAudioProcessor& p)
14+
: AudioProcessorEditor (&p), audioProcessor (p)
15+
{
16+
delayGroup.setText("Delay");
17+
delayGroup.setTextLabelPosition(juce::Justification::horizontallyCentred);
18+
delayGroup.addAndMakeVisible(delayTimeKnob);
19+
addAndMakeVisible(delayGroup);
20+
21+
feedbackGroup.setText("Feedback");
22+
feedbackGroup.setTextLabelPosition(juce::Justification::horizontallyCentred);
23+
addAndMakeVisible(feedbackGroup);
24+
25+
outputGroup.setText("Output");
26+
outputGroup.setTextLabelPosition(juce::Justification::horizontallyCentred);
27+
outputGroup.addAndMakeVisible(gainKnob);
28+
outputGroup.addAndMakeVisible(mixKnob);
29+
addAndMakeVisible(outputGroup);
30+
31+
setSize(500, 330);
32+
}
33+
34+
DelayAudioProcessorEditor::~DelayAudioProcessorEditor()
35+
{
36+
}
37+
38+
//==============================================================================
39+
void DelayAudioProcessorEditor::paint (juce::Graphics& g)
40+
{
41+
g.fillAll(juce::Colours::darkgrey);
42+
}
43+
44+
void DelayAudioProcessorEditor::resized()
45+
{
46+
auto bounds = getLocalBounds();
47+
48+
int y = 10;
49+
int height = bounds.getHeight() - 20;
50+
51+
// Position the groups
52+
delayGroup.setBounds(10, y, 110, height);
53+
54+
outputGroup.setBounds(bounds.getWidth() - 160, y, 150, height);
55+
56+
feedbackGroup.setBounds(delayGroup.getRight() + 10, y,
57+
outputGroup.getX() - delayGroup.getRight() - 20,
58+
height);
59+
60+
// Position the knobs inside the groups
61+
delayTimeKnob.setTopLeftPosition(20, 20);
62+
mixKnob.setTopLeftPosition(20, 20);
63+
gainKnob.setTopLeftPosition(mixKnob.getX(), mixKnob.getBottom() + 10);
64+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
==============================================================================
3+
4+
This file contains the basic framework code for a JUCE plugin editor.
5+
6+
==============================================================================
7+
*/
8+
9+
#pragma once
10+
11+
#include <JuceHeader.h>
12+
#include "PluginProcessor.h"
13+
#include "Parameters.h"
14+
#include "RotaryKnob.h"
15+
16+
//==============================================================================
17+
/**
18+
*/
19+
class DelayAudioProcessorEditor : public juce::AudioProcessorEditor
20+
{
21+
public:
22+
DelayAudioProcessorEditor (DelayAudioProcessor&);
23+
~DelayAudioProcessorEditor() override;
24+
25+
//==============================================================================
26+
void paint (juce::Graphics&) override;
27+
void resized() override;
28+
29+
private:
30+
// This reference is provided as a quick way for your editor to
31+
// access the processor object that created it.
32+
DelayAudioProcessor& audioProcessor;
33+
34+
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DelayAudioProcessorEditor)
35+
36+
RotaryKnob gainKnob { "Gain", audioProcessor.apvts, gainParamID };
37+
RotaryKnob mixKnob { "Mix", audioProcessor.apvts, mixParamID };
38+
RotaryKnob delayTimeKnob { "Time", audioProcessor.apvts, delayTimeParamID };
39+
40+
juce::GroupComponent delayGroup, feedbackGroup, outputGroup;
41+
};

0 commit comments

Comments
 (0)