mirror of
https://codeberg.org/armin/horizont.git
synced 2026-09-01 04:10:46 +02:00
update
This commit is contained in:
parent
ed28db30a3
commit
6c0d072465
19 changed files with 2212 additions and 0 deletions
218
Source/HorizontEngine.h
Normal file
218
Source/HorizontEngine.h
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
#pragma once
|
||||
|
||||
#include <JuceHeader.h>
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "PitchShifter.h"
|
||||
|
||||
class HorizontEngine
|
||||
{
|
||||
public:
|
||||
HorizontEngine();
|
||||
|
||||
void prepare (double sampleRate);
|
||||
void reset();
|
||||
|
||||
void setLowCut (float hz);
|
||||
void setHighCut (float hz);
|
||||
void setDecay (float seconds);
|
||||
void setSize (float size);
|
||||
void setDiffusion (float diffusion);
|
||||
void setBrightness (float brightness);
|
||||
void setFeedback (float feedback);
|
||||
void setPitch (float semitones);
|
||||
void setDryWet (float dryWet);
|
||||
|
||||
void processSample (float inL, float inR, float& outL, float& outR);
|
||||
|
||||
float getLastWetL() const noexcept { return lastWetL; }
|
||||
float getLastWetR() const noexcept { return lastWetR; }
|
||||
|
||||
private:
|
||||
struct SVF
|
||||
{
|
||||
void reset()
|
||||
{
|
||||
ic1 = 0.0f;
|
||||
ic2 = 0.0f;
|
||||
g = 0.0f;
|
||||
}
|
||||
|
||||
void setG (float gIn)
|
||||
{
|
||||
g = gIn;
|
||||
a1 = 1.0f / (1.0f + g * (g + k));
|
||||
a2 = g * a1;
|
||||
}
|
||||
|
||||
void process (float x)
|
||||
{
|
||||
const float v3 = x - ic2;
|
||||
const float v1 = a1 * ic1 + a2 * v3;
|
||||
const float v2 = ic2 + g * v1;
|
||||
ic1 = 2.0f * v1 - ic1;
|
||||
ic2 = 2.0f * v2 - ic2;
|
||||
low = v2;
|
||||
high = x - k * v1 - v2;
|
||||
}
|
||||
|
||||
float g = 0.0f;
|
||||
float k = 1.41421356f;
|
||||
float a1 = 0.0f;
|
||||
float a2 = 0.0f;
|
||||
float ic1 = 0.0f;
|
||||
float ic2 = 0.0f;
|
||||
float low = 0.0f;
|
||||
float high = 0.0f;
|
||||
};
|
||||
|
||||
struct Allpass
|
||||
{
|
||||
void prepare (int length)
|
||||
{
|
||||
len = length;
|
||||
xb.assign ((size_t) len + 1, 0.0f);
|
||||
yb.assign ((size_t) len + 1, 0.0f);
|
||||
writePos = 0;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
std::fill (xb.begin(), xb.end(), 0.0f);
|
||||
std::fill (yb.begin(), yb.end(), 0.0f);
|
||||
writePos = 0;
|
||||
}
|
||||
|
||||
float process (float x, float g)
|
||||
{
|
||||
int rp = writePos - len;
|
||||
if (rp < 0)
|
||||
rp += len + 1;
|
||||
|
||||
const float xd = xb[(size_t) rp];
|
||||
const float yd = yb[(size_t) rp];
|
||||
xb[(size_t) writePos] = x;
|
||||
|
||||
const float y = -g * x + xd + g * yd;
|
||||
yb[(size_t) writePos] = y;
|
||||
|
||||
++writePos;
|
||||
if (writePos > len)
|
||||
writePos = 0;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
std::vector<float> xb;
|
||||
std::vector<float> yb;
|
||||
int len = 0;
|
||||
int writePos = 0;
|
||||
};
|
||||
|
||||
struct Comb
|
||||
{
|
||||
void prepare (int maxLength)
|
||||
{
|
||||
buffer.assign ((size_t) maxLength + 4, 0.0f);
|
||||
maxLen = maxLength;
|
||||
writePos = 0;
|
||||
dampState = 0.0f;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
std::fill (buffer.begin(), buffer.end(), 0.0f);
|
||||
dampState = 0.0f;
|
||||
writePos = 0;
|
||||
}
|
||||
|
||||
float process (float input, float delayLen, float dampCoef, float gain)
|
||||
{
|
||||
const float rp = (float) writePos - delayLen;
|
||||
int i0 = (int) std::floor (rp);
|
||||
const float frac = rp - (float) i0;
|
||||
|
||||
i0 %= maxLen;
|
||||
if (i0 < 0)
|
||||
i0 += maxLen;
|
||||
|
||||
int i1 = i0 + 1;
|
||||
if (i1 >= maxLen)
|
||||
i1 -= maxLen;
|
||||
|
||||
const float y = buffer[(size_t) i0] + frac * (buffer[(size_t) i1] - buffer[(size_t) i0]);
|
||||
|
||||
buffer[(size_t) writePos] = input + dampState * gain;
|
||||
dampState += dampCoef * (y - dampState);
|
||||
|
||||
++writePos;
|
||||
if (writePos >= maxLen)
|
||||
writePos = 0;
|
||||
|
||||
return dampState;
|
||||
}
|
||||
|
||||
std::vector<float> buffer;
|
||||
int maxLen = 0;
|
||||
int writePos = 0;
|
||||
float dampState = 0.0f;
|
||||
};
|
||||
|
||||
struct DCBlock
|
||||
{
|
||||
void reset()
|
||||
{
|
||||
xm = 0.0f;
|
||||
ym = 0.0f;
|
||||
}
|
||||
|
||||
float process (float x)
|
||||
{
|
||||
const float y = x - xm + 0.999f * ym;
|
||||
xm = x;
|
||||
ym = y;
|
||||
return y;
|
||||
}
|
||||
|
||||
float xm = 0.0f;
|
||||
float ym = 0.0f;
|
||||
};
|
||||
|
||||
static constexpr std::array<float, 8> baseLen441 = { 1553.f, 1787.f, 2017.f, 2237.f, 2437.f, 2657.f, 2879.f, 3073.f };
|
||||
static constexpr std::array<float, 8> rightOffset = { 79.f, 67.f, 53.f, 41.f, 29.f, 23.f, 13.f, 7.f };
|
||||
|
||||
double sampleRate = 44100.0;
|
||||
|
||||
juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear> lowCutG;
|
||||
juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear> highCutG;
|
||||
juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear> decayS;
|
||||
juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear> sizeS;
|
||||
juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear> diffS;
|
||||
juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear> dampS;
|
||||
juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear> feedbackS;
|
||||
juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear> ratioS;
|
||||
juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear> wetS;
|
||||
|
||||
SVF hpL, lpL, hpR, lpR;
|
||||
DCBlock dcL, dcR;
|
||||
Allpass diffL1, diffL2, diffR1, diffR2;
|
||||
PitchShifter shiftL, shiftR;
|
||||
std::array<Comb, 8> combL;
|
||||
std::array<Comb, 8> combR;
|
||||
std::array<float, 8> baseLen;
|
||||
std::array<float, 8> baseLenR;
|
||||
|
||||
float lowCutHz = 40.0f;
|
||||
float highCutHz = 14000.0f;
|
||||
float decaySec = 3.5f;
|
||||
float sizeVal = 1.0f;
|
||||
float diffusionVal = 0.6f;
|
||||
float brightnessVal = 0.75f;
|
||||
float feedbackVal = 0.6f;
|
||||
float pitchVal = 0.0f;
|
||||
float dryWetVal = 0.35f;
|
||||
|
||||
float lastWetL = 0.0f;
|
||||
float lastWetR = 0.0f;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue