Skip to content

Commit

Permalink
feat: add computer
Browse files Browse the repository at this point in the history
  • Loading branch information
zsliu98 committed Aug 28, 2024
1 parent 79f8c5f commit 00e4206
Show file tree
Hide file tree
Showing 10 changed files with 476 additions and 12 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ include(SharedCodeDefaults)
# Just ensure you employ CONFIGURE_DEPENDS so the build system picks up changes
# If you want to appease the CMake gods and avoid globs, manually add files like so:
# set(SourceFiles Source/PluginEditor.h Source/PluginProcessor.h Source/PluginEditor.cpp Source/PluginProcessor.cpp)
file(GLOB_RECURSE SourceFiles CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/source/*.h")
file(GLOB_RECURSE SourceFiles CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/source/*.hpp")
target_sources(SharedCode INTERFACE ${SourceFiles})

# Adds a BinaryData target for embedding assets into the binary
Expand Down
9 changes: 9 additions & 0 deletions source/PluginEditor.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
// Copyright (C) 2024 - zsliu98
// This file is part of ZLCompressor
//
// ZLCompressor is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
//
// ZLCompressor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with ZLCompressor. If not, see <https://www.gnu.org/licenses/>.

#include "PluginEditor.h"

PluginEditor::PluginEditor(PluginProcessor &p)
Expand Down
9 changes: 9 additions & 0 deletions source/PluginEditor.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
// Copyright (C) 2024 - zsliu98
// This file is part of ZLCompressor
//
// ZLCompressor is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
//
// ZLCompressor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with ZLCompressor. If not, see <https://www.gnu.org/licenses/>.

#pragma once

#include "PluginProcessor.h"
Expand Down
29 changes: 19 additions & 10 deletions source/PluginProcessor.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
// Copyright (C) 2024 - zsliu98
// This file is part of ZLCompressor
//
// ZLCompressor is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
//
// ZLCompressor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with ZLCompressor. If not, see <https://www.gnu.org/licenses/>.

#include "PluginProcessor.h"
#include "PluginEditor.h"

//==============================================================================
PluginProcessor::PluginProcessor()
: AudioProcessor(BusesProperties()
#if !JucePlugin_IsMidiEffect
#if !JucePlugin_IsSynth
.withInput("Input", juce::AudioChannelSet::stereo(), true)
#endif
.withOutput("Output", juce::AudioChannelSet::stereo(), true)
#endif
) {
: AudioProcessor(BusesProperties()
.withInput("Input", juce::AudioChannelSet::stereo(), true)
.withInput("Aux", juce::AudioChannelSet::stereo(), true)
.withOutput("Output", juce::AudioChannelSet::stereo(), true)
), parameters(*this, nullptr,
juce::Identifier("ZLCompressorParameters"),
zlDSP::getParameterLayout()) {
}

PluginProcessor::~PluginProcessor() {
Expand Down Expand Up @@ -50,7 +58,7 @@ double PluginProcessor::getTailLengthSeconds() const {
}

int PluginProcessor::getNumPrograms() {
return 1; // NB: some hosts don't cope very well if you tell them there are 0 programs,
return 1; // NB: some hosts don't cope very well if you tell them there are 0 programs,
// so this should be at least 1, even if you're not really implementing programs.
}

Expand Down Expand Up @@ -140,7 +148,8 @@ bool PluginProcessor::hasEditor() const {
}

juce::AudioProcessorEditor *PluginProcessor::createEditor() {
return new PluginEditor(*this);
// return new PluginEditor(*this);
return new juce::GenericAudioProcessorEditor(*this);
}

//==============================================================================
Expand Down
15 changes: 14 additions & 1 deletion source/PluginProcessor.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
// Copyright (C) 2024 - zsliu98
// This file is part of ZLCompressor
//
// ZLCompressor is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
//
// ZLCompressor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with ZLCompressor. If not, see <https://www.gnu.org/licenses/>.

#pragma once

#include <juce_audio_processors/juce_audio_processors.h>

#include "dsp/dsp.hpp"

#if (MSVC)
#include "ipps.h"
#endif

class PluginProcessor : public juce::AudioProcessor {
class PluginProcessor final : public juce::AudioProcessor {
public:
juce::AudioProcessorValueTreeState parameters;

PluginProcessor();

~PluginProcessor() override;
Expand Down
15 changes: 15 additions & 0 deletions source/dsp/computer/computer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (C) 2024 - zsliu98
// This file is part of ZLCompressor
//
// ZLCompressor is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
//
// ZLCompressor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with ZLCompressor. If not, see <https://www.gnu.org/licenses/>.

#ifndef COMPRESSOR_COMPUTER_HPP
#define COMPRESSOR_COMPUTER_HPP

#include "knee_computer.hpp"

#endif //COMPRESSOR_COMPUTER_HPP
73 changes: 73 additions & 0 deletions source/dsp/computer/knee_computer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (C) 2024 - zsliu98
// This file is part of ZLCompressor
//
// ZLCompressor is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
//
// ZLCompressor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with ZLCompressor. If not, see <https://www.gnu.org/licenses/>.

#include "knee_computer.hpp"

namespace zlCompressor {
template<typename FloatType>
KneeComputer<FloatType>::KneeComputer(const KneeComputer<FloatType> &c) {
setThreshold(c.getThreshold());
setRatio(c.getRatio());
setKneeW(c.getKneeW());
setCurve(c.getCurve());
setBound(c.getBound());
}

template<typename FloatType>
KneeComputer<FloatType>::~KneeComputer() = default;

template<typename FloatType>
FloatType KneeComputer<FloatType>::eval(FloatType x) {
if (toInterpolate.exchange(false)) {
interpolate();
}
if (x <= lowThres) {
return x;
} else if (x >= highThres) {
const auto linearV = paras[5] + x * currentSlope;
const auto quadV = paras[3] * x * x + paras[4];
return juce::jlimit(x - currentBound, x + currentBound,
currentOppositeCurve * linearV + currentCurve * quadV);
} else {
const auto xx = x + paras[1];
return juce::jlimit(x - currentBound, x + currentBound,
x + paras[0] * xx * xx * paras[2]);
}
}

template<typename FloatType>
FloatType KneeComputer<FloatType>::process(FloatType x) {
return eval(x) - x;
}

template<typename FloatType>
void KneeComputer<FloatType>::interpolate() {
currentThreshold = threshold.load();
const auto kneeW_ = kneeW.load();
currentRatio = ratio.load();
currentSlope = FloatType(1) / currentRatio;
currentBound = bound.load();
currentCurve = curve.load();
currentOppositeCurve = FloatType(1) - currentCurve;
lowThres = currentThreshold - kneeW_;
highThres = currentThreshold + kneeW_;
paras[0] = FloatType(1) / currentRatio - FloatType(1);
paras[1] = -lowThres;
paras[2] = FloatType(1) / (kneeW_ * FloatType(4));
paras[3] = 1 / std::min(currentThreshold + kneeW_, FloatType(0.0001)) / currentRatio;
paras[4] = currentThreshold + (kneeW_ - currentThreshold) / FloatType(2) / currentRatio;
paras[5] = currentThreshold * (1 - currentSlope);
}

template
class KneeComputer<float>;

template
class KneeComputer<double>;
} // KneeComputer
87 changes: 87 additions & 0 deletions source/dsp/computer/knee_computer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (C) 2024 - zsliu98
// This file is part of ZLCompressor
//
// ZLCompressor is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
//
// ZLCompressor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with ZLCompressor. If not, see <https://www.gnu.org/licenses/>.

#ifndef COMPRESSOR_COMPUTER_H
#define COMPRESSOR_COMPUTER_H

#include <juce_audio_processors/juce_audio_processors.h>

namespace zlCompressor {
/**
* a computer that computes the current compression
* @tparam FloatType
*/
template<typename FloatType>
class KneeComputer final {
public:
KneeComputer() = default;

KneeComputer(const KneeComputer<FloatType> &c);

~KneeComputer();

FloatType eval(FloatType x);

/**
* computes the current compression
* @param x input level (in dB)
* @return current compression (in dB)
*/
FloatType process(FloatType x);

inline void setThreshold(FloatType v) {
threshold.store(v);
toInterpolate.store(true);
}

inline FloatType getThreshold() const { return threshold.load(); }

inline void setRatio(FloatType v) {
ratio.store(v);
toInterpolate.store(true);
}

inline FloatType getRatio() const { return ratio.load(); }

inline void setKneeW(FloatType v) {
kneeW.store(std::max(v, FloatType(0.01)));
toInterpolate.store(true);
}

inline FloatType getKneeW() const { return kneeW.load(); }

inline void setCurve(FloatType v) {
curve.store(v);
toInterpolate.store(true);
}

inline FloatType getCurve() const { return curve.load(); }

inline void setBound(FloatType v) {
bound.store(v);
}

inline FloatType getBound() const { return bound.load(); }

private:
std::atomic<FloatType> threshold{0}, ratio{1};
FloatType currentThreshold{0}, currentRatio{1}, currentSlope{1};
std::atomic<FloatType> kneeW{FloatType(0.01)}, curve{0};
FloatType lowThres{0}, highThres{0}, currentCurve{0}, currentOppositeCurve{1};
std::atomic<FloatType> bound{60};
FloatType currentBound{60};
std::array<FloatType, 6> paras;
std::atomic<bool> toInterpolate{true};

void interpolate();
};

} // KneeComputer

#endif //COMPRESSOR_COMPUTER_H
16 changes: 16 additions & 0 deletions source/dsp/dsp.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (C) 2024 - zsliu98
// This file is part of ZLCompressor
//
// ZLCompressor is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
//
// ZLCompressor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with ZLCompressor. If not, see <https://www.gnu.org/licenses/>.

#ifndef DSP_HPP
#define DSP_HPP

#include "dsp_definitions.hpp"
#include "computer/computer.hpp"

#endif //DSP_HPP
Loading

0 comments on commit 00e4206

Please sign in to comment.