mirror of
https://codeberg.org/armin/gelyk.git
synced 2026-10-11 17:01:53 +02:00
Initial Gelyk EQ plugin
This commit is contained in:
commit
13863f4522
9 changed files with 1080 additions and 0 deletions
166
Source/PluginProcessor.cpp
Normal file
166
Source/PluginProcessor.cpp
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
#include "PluginProcessor.h"
|
||||
#include "PluginEditor.h"
|
||||
#include "GitInfo.h"
|
||||
|
||||
namespace gelyk
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
juce::AudioProcessorValueTreeState::ParameterLayout createParameterLayout()
|
||||
{
|
||||
juce::AudioProcessorValueTreeState::ParameterLayout layout;
|
||||
|
||||
auto addGain = [&](juce::String id, juce::String name, float def)
|
||||
{
|
||||
layout.add(std::make_unique<juce::AudioParameterFloat>(
|
||||
id, name, juce::NormalisableRange<float>(-24.0f, 24.0f, 0.01f), def));
|
||||
};
|
||||
|
||||
auto addQ = [&](juce::String id, juce::String name, float def)
|
||||
{
|
||||
layout.add(std::make_unique<juce::AudioParameterFloat>(
|
||||
id, name, juce::NormalisableRange<float>(0.1f, 6.0f, 0.01f), def));
|
||||
};
|
||||
|
||||
addGain("gain0", "Low Shelf Gain", 0.0f);
|
||||
addGain("gain1", "Low-Mid Gain", 0.0f);
|
||||
addGain("gain2", "Mid Gain", 0.0f);
|
||||
addGain("gain3", "High-Mid Gain", 0.0f);
|
||||
addGain("gain4", "High Shelf Gain", 0.0f);
|
||||
|
||||
addQ("q0", "Low Shelf Q", 0.71f);
|
||||
addQ("q1", "Low-Mid Q", 1.0f);
|
||||
addQ("q2", "Mid Q", 1.0f);
|
||||
addQ("q3", "High-Mid Q", 1.0f);
|
||||
addQ("q4", "High Shelf Q", 0.71f);
|
||||
|
||||
layout.add(std::make_unique<juce::AudioParameterFloat>(
|
||||
"master", "Master", juce::NormalisableRange<float>(-24.0f, 24.0f, 0.01f), 0.0f));
|
||||
|
||||
layout.add(std::make_unique<juce::AudioParameterBool>(
|
||||
"analyserEnabled", "Analyser", true));
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
const char* const bandTypes[5] = { "lowShelf", "peak", "peak", "peak", "highShelf" };
|
||||
const float bandFreqs[5] = { 60.0f, 200.0f, 1000.0f, 4000.0f, 10000.0f };
|
||||
} // namespace
|
||||
|
||||
GelykEQAudioProcessor::GelykEQAudioProcessor()
|
||||
: AudioProcessor(BusesProperties()
|
||||
.withInput("Input", juce::AudioChannelSet::stereo(), true)
|
||||
.withOutput("Output", juce::AudioChannelSet::stereo(), true)),
|
||||
apvts(*this, nullptr, "Parameters", createParameterLayout())
|
||||
{
|
||||
buildVersion = ProjectInfo::versionString;
|
||||
|
||||
gitInfo = juce::String(GELYK_GIT_BRANCH) + " @ " + juce::String(GELYK_GIT_SHA) +
|
||||
(juce::String(GELYK_GIT_DIRTY_STR).isNotEmpty() ? " (dirty)" : "") +
|
||||
" | " + juce::String(GELYK_BUILD_DATE_STR);
|
||||
}
|
||||
|
||||
void GelykEQAudioProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
|
||||
{
|
||||
currentSampleRate = sampleRate;
|
||||
|
||||
for (int i = 0; i < numBands; ++i)
|
||||
{
|
||||
bands[i].type = (FilterBand::Type)
|
||||
(juce::String(bandTypes[i]) == "lowShelf" ? 0 :
|
||||
(juce::String(bandTypes[i]) == "highShelf" ? 2 : 1));
|
||||
bands[i].freq = bandFreqs[i];
|
||||
bands[i].prepare(sampleRate, samplesPerBlock);
|
||||
bands[i].reset();
|
||||
}
|
||||
|
||||
analyser.prepare(sampleRate, samplesPerBlock);
|
||||
analyser.startBackground();
|
||||
|
||||
rebuildCoefficients();
|
||||
}
|
||||
|
||||
void GelykEQAudioProcessor::releaseResources()
|
||||
{
|
||||
analyser.stopBackground();
|
||||
}
|
||||
|
||||
void GelykEQAudioProcessor::rebuildCoefficients()
|
||||
{
|
||||
for (int i = 0; i < numBands; ++i)
|
||||
{
|
||||
float gain = apvts.getRawParameterValue("gain" + juce::String(i))->load();
|
||||
float q = apvts.getRawParameterValue("q" + juce::String(i))->load();
|
||||
bands[i].gainDb = gain;
|
||||
bands[i].q = q;
|
||||
bands[i].prepare(currentSampleRate, 512);
|
||||
}
|
||||
}
|
||||
|
||||
void GelykEQAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, juce::MidiBuffer&)
|
||||
{
|
||||
juce::ScopedNoDenormals noDenormals;
|
||||
|
||||
const int numChannels = buffer.getNumChannels();
|
||||
const int numSamples = buffer.getNumSamples();
|
||||
|
||||
if (numChannels < 1)
|
||||
return;
|
||||
|
||||
// Feed the analyser with the input.
|
||||
if (apvts.getRawParameterValue("analyserEnabled")->load() > 0.5f)
|
||||
{
|
||||
const float* chans[2] = { buffer.getReadPointer(0),
|
||||
numChannels > 1 ? buffer.getReadPointer(1) : buffer.getReadPointer(0) };
|
||||
analyser.push(chans, numChannels > 1 ? 2 : 1, numSamples);
|
||||
}
|
||||
|
||||
// Refresh band coefficients (cheap) from smoothed params each block.
|
||||
for (int i = 0; i < numBands; ++i)
|
||||
{
|
||||
float gain = apvts.getRawParameterValue("gain" + juce::String(i))->load();
|
||||
float q = apvts.getRawParameterValue("q" + juce::String(i))->load();
|
||||
if (std::abs(gain - bands[i].gainDb) > 0.001f || std::abs(q - bands[i].q) > 0.001f)
|
||||
{
|
||||
bands[i].gainDb = gain;
|
||||
bands[i].q = q;
|
||||
bands[i].prepare(currentSampleRate, numSamples);
|
||||
}
|
||||
}
|
||||
|
||||
juce::dsp::AudioBlock<float> block(buffer);
|
||||
|
||||
for (int i = 0; i < numBands; ++i)
|
||||
bands[i].process(block);
|
||||
|
||||
float master = apvts.getRawParameterValue("master")->load();
|
||||
if (std::abs(master) > 0.001f)
|
||||
buffer.applyGain(juce::Decibels::decibelsToGain(master));
|
||||
}
|
||||
|
||||
void GelykEQAudioProcessor::getStateInformation(juce::MemoryBlock& destData)
|
||||
{
|
||||
auto state = apvts.copyState();
|
||||
std::unique_ptr<juce::XmlElement> xml(state.createXml());
|
||||
copyXmlToBinary(*xml, destData);
|
||||
}
|
||||
|
||||
void GelykEQAudioProcessor::setStateInformation(const void* data, int sizeInBytes)
|
||||
{
|
||||
std::unique_ptr<juce::XmlElement> xml(getXmlFromBinary(data, sizeInBytes));
|
||||
if (xml != nullptr && xml->hasTagName(apvts.state.getType()))
|
||||
apvts.replaceState(juce::ValueTree::fromXml(*xml));
|
||||
}
|
||||
|
||||
juce::AudioProcessorEditor* GelykEQAudioProcessor::createEditor()
|
||||
{
|
||||
return new GelykEQAudioProcessorEditor(*this);
|
||||
}
|
||||
|
||||
} // namespace gelyk
|
||||
|
||||
juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter()
|
||||
{
|
||||
return new gelyk::GelykEQAudioProcessor();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue