Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ else()
endif()




target_sources(kAmp
PRIVATE
${SOURCES})
Expand Down Expand Up @@ -111,6 +113,7 @@ target_link_libraries(kAmp
juce::juce_audio_basics
juce::juce_audio_utils
juce::juce_gui_extra
juce::juce_dsp
PUBLIC
juce::juce_recommended_config_flags
juce::juce_recommended_lto_flags
Expand Down
2 changes: 1 addition & 1 deletion include/DistortionEffect.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class DistortionEffect : public AbstractEffect {
*/
void setRange(float rangeValue);

static float DistortionEffect::clipWithCurrentRange(float x);
static float clipWithCurrentRange(float x);



Expand Down
29 changes: 29 additions & 0 deletions include/EqualizerEffect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <JuceHeader.h>
#include "AbstractEffect.h"
#include <juce_dsp/juce_dsp.h>


class EqualizerEffect : public AbstractEffect {
public:
EqualizerEffect();
~EqualizerEffect() override = default;

void apply(const AudioSourceChannelInfo &bufferToFill) override;
void setGain(int bandIndex, float gain);
float getGain(int bandIndex) const;
bool operator==(const AbstractEffect* effect) override;

[[nodiscard]] String getEffectType() const override { return "EqualizerEffect"; }

[[nodiscard]] var toJSON() const override;
void fromJSON(const var &json) override;

private:
static constexpr int numBands = 10;
float bandGains[numBands]; // Gain en dB pour chaque bande
std::vector<dsp::IIR::Filter<float>> filters;

void updateFilters();
};
22 changes: 22 additions & 0 deletions include/EqualizerEffectComponent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <juce_gui_basics/juce_gui_basics.h>
#include "BasePedalComponent.h"
#include "EqualizerEffect.h"

class EqualizerEffectComponent : public BasePedalComponent {
public:
explicit EqualizerEffectComponent(AbstractEffect* effect);
~EqualizerEffectComponent() override = default;

private:
EqualizerEffect* eqEffect;
Slider sliders[10];
Label labels[10];

Grid grid;

void sliderValueChanged(Slider* slider);

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(EqualizerEffectComponent)
};
6 changes: 6 additions & 0 deletions src/EffectComponentFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "DistortionEffect.h"
#include "DistortionEffectComponent.h"
#include "EffectComponentFactory.h"
#include "EqualizerEffect.h"
#include "EqualizerEffectComponent.h"
#include "NoiseGateEffect.h"
#include "NoiseGateEffectComponent.h"

Expand All @@ -13,6 +15,10 @@ EffectComponent* EffectComponentFactory::CreateEffectComponent(AbstractEffect* e
if (dynamic_cast<DistortionEffect*>(effect) != nullptr) {
return new DistortionEffectComponent(effect);
}
if (dynamic_cast<EqualizerEffect*>(effect) != nullptr)
{
return new EqualizerEffectComponent(effect);
}
if (dynamic_cast<NoiseGateEffect*>(effect) != nullptr) {
return new NoiseGateEffectComponent(effect);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Pedalboard.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#include "DelayEffect.h"
#include "DistortionEffect.h"
#include "Pedalboard.h"
#include "EqualizerEffect.h"
#include "NoiseGateEffect.h"

Pedalboard::Pedalboard() {
this->append(new DelayEffect());
this->append(new DistortionEffect());
this->append(new EqualizerEffect());
this->append(new NoiseGateEffect());
}

Expand Down
3 changes: 1 addition & 2 deletions src/components/DelayEffectComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ DelayEffectComponent::DelayEffectComponent(AbstractEffect* effect) : BasePedalCo
addAndMakeVisible(delaySlider);
addAndMakeVisible(delayLabel);

setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

this->initializePedal();
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/components/DistortionEffectComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ DistortionEffectComponent::DistortionEffectComponent(AbstractEffect* effect)
addAndMakeVisible(rangeSlider);
addAndMakeVisible(rangeLabel);


setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);
this->initializePedal();
setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);
}
}

Expand Down
72 changes: 72 additions & 0 deletions src/components/EqualizerEffectComponent.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "EqualizerEffectComponent.h"
#include <juce_gui_basics/juce_gui_basics.h>

#include "EqualizerEffectComponent.h"


EqualizerEffectComponent::EqualizerEffectComponent(AbstractEffect* effect)
: BasePedalComponent(effect), eqEffect(dynamic_cast<EqualizerEffect*>(effect)) {

jassert(eqEffect != nullptr);

primaryColor = juce::Colours::orange;

const char* freqLabels[10] = { "31Hz", "62Hz", "125Hz", "250Hz", "500Hz", "1k", "2k", "4k", "8k", "16k" };

using Track = juce::Grid::TrackInfo;
using Fr = juce::Grid::Fr;

// 2 lignes : sliders + labels
grid.templateRows = { Track(Fr(1)), Track(Fr(3)) };
grid.templateColumns = { Track(Fr(1)), Track(Fr(1)), Track(Fr(1)), Track(Fr(1)), Track(Fr(1)),
Track(Fr(1)), Track(Fr(1)), Track(Fr(1)), Track(Fr(1)), Track(Fr(1)) };

for (int i = 0; i < 10; ++i) {
sliders[i].setSliderStyle(juce::Slider::LinearVertical);
sliders[i].setTextBoxStyle(juce::Slider::TextBoxBelow, false, 50, 20);
sliders[i].setRange(-24.0, 24.0, 0.1);
sliders[i].setValue(0.0);
sliders[i].setColour(juce::Slider::textBoxOutlineColourId, juce::Colours::transparentWhite);
sliders[i].onValueChange = [this, i]
{
if (static_cast<float>(sliders[i].getValue())) {
eqEffect->setGain(i, static_cast<float>(sliders[i].getValue()));
}
};
sliders[i].setTitle(freqLabels[i]);
sliders[i].setBounds(i * (getWidth() / 10), 0, getWidth() / 10, (getHeight() / 5) * 4);

labels[i].setText(freqLabels[i], juce::dontSendNotification);
labels[i].setJustificationType(juce::Justification::centred);
labels[i].attachToComponent(&sliders[i], false);
labels[i].setBounds(i * (getWidth() / 10), 0, getWidth() / 10, getHeight() / 5);

addAndMakeVisible(sliders[i]);
addAndMakeVisible(labels[i]);
}

for (int i = 0; i < 10; ++i)
{
grid.items.add(GridItem(labels[i]));
}
for (int i = 0; i < 10; ++i)
{
grid.items.add(juce::GridItem(sliders[i]));
}

settingsLayout = new PedalSettingsLayoutComponent(&grid);

this->initializePedal();
setSize(400, 300);
}



void EqualizerEffectComponent::sliderValueChanged(juce::Slider* slider) {
for (int i = 0; i < 10; ++i) {
if (slider == &sliders[i]) {
eqEffect->setGain(i, slider->getValue());
break;
}
}
}
3 changes: 1 addition & 2 deletions src/components/NoiseGateEffectComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,8 @@ NoiseGateEffectComponent::NoiseGateEffectComponent(AbstractEffect* effect): Base
addAndMakeVisible(releaseSlider);
addAndMakeVisible(releaseLabel);

setSize(300, 300);

this->initializePedal();
setSize(300, 300);
}
}

Expand Down
29 changes: 10 additions & 19 deletions src/effects/DelayEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,9 @@ DelayEffect::DelayEffect() {
DelayEffect::~DelayEffect() = default;

void DelayEffect::apply(const AudioSourceChannelInfo &bufferToFill) {
if (delay > 0 && rate > 0)
{
auto* leftBuffer = bufferToFill.buffer->getWritePointer(0);
auto* rightBuffer = bufferToFill.buffer->getNumChannels() > 1
? bufferToFill.buffer->getWritePointer(1)
: nullptr;
const auto numSamples = bufferToFill.numSamples;

// TODO : Remove constants and check if they can be recovered with JUCE.
if (delay > 0 && rate > 0) {
const int numChannels = bufferToFill.buffer->getNumChannels();
const int numSamples = bufferToFill.numSamples;
constexpr auto sampleRate = 44100.0;
const auto delaySamples = static_cast<int>(delay * sampleRate / 1000.0f);

Expand All @@ -26,19 +20,16 @@ void DelayEffect::apply(const AudioSourceChannelInfo &bufferToFill) {
writePosition = 0;
}


for (int i = 0; i < numSamples; ++i) {
auto delayedSample = circularBuffer[writePosition];

auto inputSampleLeft = leftBuffer[i];
leftBuffer[i] = inputSampleLeft + delayedSample * (rate / 100.0f);

if (rightBuffer) {
auto inputSampleRight = rightBuffer[i];
rightBuffer[i] = inputSampleRight + delayedSample * (rate / 100.0f);
for (int channel = 0; channel < numChannels; ++channel)
{
auto* channelBuffer = bufferToFill.buffer->getWritePointer(channel);
auto inputSample = channelBuffer[i];
channelBuffer[i] = inputSample + delayedSample * (rate / 100.0f);
circularBuffer[writePosition] = inputSample;
}

circularBuffer[writePosition] = inputSampleLeft;

writePosition = (writePosition + 1) % delaySamples;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/effects/DistortionEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ void DistortionEffect::apply(const juce::AudioSourceChannelInfo& bufferToFill)
(size_t) bufferToFill.startSample);
auto subBlock = block.getSubBlock(0, (size_t) bufferToFill.numSamples);
juce::dsp::ProcessContextReplacing<float> context(subBlock);
subBlock.multiplyBy(1.0f / std::max(1.0f - currentRange, 0.01f)); // Normalisation du volume

process(context);
}
Expand Down
78 changes: 78 additions & 0 deletions src/effects/EqualizerEffect.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "EqualizerEffect.h"
#include <juce_dsp/juce_dsp.h>

EqualizerEffect::EqualizerEffect() {
effectName = "Equalizer";
filters.resize(numBands);
for (int i = 0; i < numBands; ++i) bandGains[i] = 0.0f;
updateFilters();
}

void EqualizerEffect::apply(const juce::AudioSourceChannelInfo &bufferToFill) {
auto* buffer = bufferToFill.buffer;
const int numChannels = buffer->getNumChannels();
const int numSamples = bufferToFill.numSamples;

juce::dsp::AudioBlock<float> block(*buffer);

for (int channel = 0; channel < numChannels; ++channel) {
auto channelBlock = block.getSingleChannelBlock((size_t)channel);
juce::dsp::ProcessContextReplacing<float> context(channelBlock);

for (int i = 0; i < numBands; ++i) {
filters[i].process(context);
}
}
}

void EqualizerEffect::setGain(int bandIndex, float gain) {
if (bandIndex >= 0 && bandIndex < numBands) {
bandGains[bandIndex] = gain;
updateFilters();
}
}

float EqualizerEffect::getGain(int bandIndex) const {
return (bandIndex >= 0 && bandIndex < numBands) ? bandGains[bandIndex] : 0.0f;
}

void EqualizerEffect::updateFilters() {
// Fréquences fixes typiques d'un égaliseur 10 bandes
const float freqs[10] = {31, 62, 125, 250, 500, 1000, 2000, 4000, 8000, 16000};
constexpr float sampleRate = 44100.0f;

for (int i = 0; i < numBands; ++i) {
filters[i].reset();
auto coeffs = juce::dsp::IIR::Coefficients<float>::makePeakFilter(
sampleRate, freqs[i], 1.0f, juce::Decibels::decibelsToGain(bandGains[i])
);
filters[i].coefficients = coeffs;
}
}

bool EqualizerEffect::operator==(const AbstractEffect* effect) {
return this == effect;
}

juce::var EqualizerEffect::toJSON() const {
auto obj = AbstractEffect::toJSON();
if (auto *dynamicObj = obj.getDynamicObject()) {
juce::Array<juce::var> gains;
for (float g : bandGains) gains.add(g);
dynamicObj->setProperty("bandGains", gains);
}
return obj;
}

void EqualizerEffect::fromJSON(const juce::var &json) {
AbstractEffect::fromJSON(json);
if (const auto* obj = json.getDynamicObject()) {
const auto& gains = obj->getProperty("bandGains");
if (auto* arr = gains.getArray()) {
for (int i = 0; i < juce::jmin((int)arr->size(), numBands); ++i) {
bandGains[i] = static_cast<float>((*arr)[i]);
}
updateFilters();
}
}
}
20 changes: 10 additions & 10 deletions src/utils/ResourceManager.cpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
#include "ResourceManager.h"

ResourceManager::ResourceManager() {}
ResourceManager::~ResourceManager() {}
ResourceManager::ResourceManager() = default;
ResourceManager::~ResourceManager() = default;

juce::Image ResourceManager::loadImage(const juce::String& relativePath)
Image ResourceManager::loadImage(const String& relativePath)
{
juce::File imageFile;
File imageFile;

#if JUCE_MAC
imageFile = juce::File::getSpecialLocation(juce::File::currentApplicationFile)
.getParentDirectory()
.getParentDirectory()
.getParentDirectory()
.getChildFile(relativePath);
imageFile = File::getSpecialLocation(File::currentApplicationFile)
.getParentDirectory()
.getParentDirectory()
.getParentDirectory()
.getChildFile(relativePath);
#else
imageFile = juce::File::getCurrentWorkingDirectory().getChildFile(relativePath);
#endif

juce::Image image = juce::ImageFileFormat::loadFrom(imageFile);
Image image = ImageFileFormat::loadFrom(imageFile);

if (image.isNull())
{
Expand Down