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.cpp
Normal file
218
Source/HorizontEngine.cpp
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
#include "HorizontEngine.h"
|
||||
|
||||
HorizontEngine::HorizontEngine()
|
||||
{
|
||||
prepare (44100.0);
|
||||
}
|
||||
|
||||
void HorizontEngine::prepare (double sr)
|
||||
{
|
||||
sampleRate = sr;
|
||||
const float srScale = (float) (sr / 44100.0);
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
baseLen[(size_t) i] = baseLen441[(size_t) i] * srScale;
|
||||
baseLenR[(size_t) i] = (baseLen441[(size_t) i] + rightOffset[(size_t) i]) * srScale;
|
||||
|
||||
const int maxL = (int) std::ceil (baseLen441[(size_t) i] * 2.0f * srScale) + 8;
|
||||
combL[(size_t) i].prepare (maxL);
|
||||
combR[(size_t) i].prepare (maxL);
|
||||
}
|
||||
|
||||
diffL1.prepare ((int) (221.0f * srScale));
|
||||
diffL2.prepare ((int) (113.0f * srScale));
|
||||
diffR1.prepare ((int) (229.0f * srScale));
|
||||
diffR2.prepare ((int) (107.0f * srScale));
|
||||
|
||||
shiftL.prepare (sr);
|
||||
shiftR.prepare (sr);
|
||||
|
||||
lowCutG.reset (sr, 0.04);
|
||||
setLowCut (lowCutHz);
|
||||
lowCutG.setCurrentAndTargetValue (lowCutG.getTargetValue());
|
||||
|
||||
highCutG.reset (sr, 0.04);
|
||||
setHighCut (highCutHz);
|
||||
highCutG.setCurrentAndTargetValue (highCutG.getTargetValue());
|
||||
|
||||
decayS.reset (sr, 0.06);
|
||||
setDecay (decaySec);
|
||||
decayS.setCurrentAndTargetValue (decayS.getTargetValue());
|
||||
|
||||
sizeS.reset (sr, 0.06);
|
||||
setSize (sizeVal);
|
||||
sizeS.setCurrentAndTargetValue (sizeS.getTargetValue());
|
||||
|
||||
diffS.reset (sr, 0.05);
|
||||
setDiffusion (diffusionVal);
|
||||
diffS.setCurrentAndTargetValue (diffS.getTargetValue());
|
||||
|
||||
dampS.reset (sr, 0.05);
|
||||
setBrightness (brightnessVal);
|
||||
dampS.setCurrentAndTargetValue (dampS.getTargetValue());
|
||||
|
||||
feedbackS.reset (sr, 0.06);
|
||||
setFeedback (feedbackVal);
|
||||
feedbackS.setCurrentAndTargetValue (feedbackS.getTargetValue());
|
||||
|
||||
ratioS.reset (sr, 0.08);
|
||||
setPitch (pitchVal);
|
||||
ratioS.setCurrentAndTargetValue (ratioS.getTargetValue());
|
||||
|
||||
wetS.reset (sr, 0.03);
|
||||
setDryWet (dryWetVal);
|
||||
wetS.setCurrentAndTargetValue (wetS.getTargetValue());
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
void HorizontEngine::reset()
|
||||
{
|
||||
for (auto& c : combL)
|
||||
c.reset();
|
||||
for (auto& c : combR)
|
||||
c.reset();
|
||||
|
||||
diffL1.reset();
|
||||
diffL2.reset();
|
||||
diffR1.reset();
|
||||
diffR2.reset();
|
||||
|
||||
hpL.reset();
|
||||
lpL.reset();
|
||||
hpR.reset();
|
||||
lpR.reset();
|
||||
|
||||
dcL.reset();
|
||||
dcR.reset();
|
||||
|
||||
shiftL.reset();
|
||||
shiftR.reset();
|
||||
|
||||
lastWetL = 0.0f;
|
||||
lastWetR = 0.0f;
|
||||
}
|
||||
|
||||
void HorizontEngine::setLowCut (float hz)
|
||||
{
|
||||
lowCutHz = hz;
|
||||
hz = juce::jmin (hz, (float) (sampleRate * 0.48));
|
||||
lowCutG.setTargetValue (std::tan (juce::MathConstants<float>::pi * hz / (float) sampleRate));
|
||||
}
|
||||
|
||||
void HorizontEngine::setHighCut (float hz)
|
||||
{
|
||||
highCutHz = hz;
|
||||
hz = juce::jmin (hz, (float) (sampleRate * 0.48));
|
||||
highCutG.setTargetValue (std::tan (juce::MathConstants<float>::pi * hz / (float) sampleRate));
|
||||
}
|
||||
|
||||
void HorizontEngine::setDecay (float seconds)
|
||||
{
|
||||
decaySec = seconds;
|
||||
decayS.setTargetValue (juce::jmax (0.1f, seconds));
|
||||
}
|
||||
|
||||
void HorizontEngine::setSize (float size)
|
||||
{
|
||||
sizeVal = size;
|
||||
sizeS.setTargetValue (juce::jlimit (0.2f, 2.5f, size));
|
||||
}
|
||||
|
||||
void HorizontEngine::setDiffusion (float diffusion)
|
||||
{
|
||||
diffusionVal = diffusion;
|
||||
diffS.setTargetValue (0.72f * juce::jlimit (0.0f, 1.0f, diffusion));
|
||||
}
|
||||
|
||||
void HorizontEngine::setBrightness (float brightness)
|
||||
{
|
||||
brightnessVal = brightness;
|
||||
const float b = juce::jlimit (0.0f, 1.0f, brightness);
|
||||
float fc = 500.0f + 19500.0f * std::pow (b, 1.5f);
|
||||
fc = juce::jmin (fc, (float) (sampleRate * 0.48f));
|
||||
dampS.setTargetValue (1.0f - std::exp (-2.0f * juce::MathConstants<float>::pi * fc / (float) sampleRate));
|
||||
}
|
||||
|
||||
void HorizontEngine::setFeedback (float feedback)
|
||||
{
|
||||
feedbackVal = feedback;
|
||||
feedbackS.setTargetValue (juce::jlimit (0.0f, 0.99f, feedback));
|
||||
}
|
||||
|
||||
void HorizontEngine::setPitch (float semitones)
|
||||
{
|
||||
pitchVal = semitones;
|
||||
ratioS.setTargetValue (std::pow (2.0f, semitones / 12.0f));
|
||||
}
|
||||
|
||||
void HorizontEngine::setDryWet (float dryWet)
|
||||
{
|
||||
dryWetVal = dryWet;
|
||||
wetS.setTargetValue (juce::jlimit (0.0f, 1.0f, dryWet));
|
||||
}
|
||||
|
||||
void HorizontEngine::processSample (float inL, float inR, float& outL, float& outR)
|
||||
{
|
||||
const float sizeCur = sizeS.getNextValue();
|
||||
const float rtCur = decayS.getNextValue();
|
||||
const float dampC = dampS.getNextValue();
|
||||
const float diffG = diffS.getNextValue();
|
||||
const float fbGain = feedbackS.getNextValue();
|
||||
const float ratio = ratioS.getNextValue();
|
||||
const float wetVal = wetS.getNextValue();
|
||||
const float gLow = lowCutG.getNextValue();
|
||||
const float gHigh = highCutG.getNextValue();
|
||||
|
||||
hpL.setG (gLow);
|
||||
hpL.process (inL);
|
||||
lpL.setG (gHigh);
|
||||
lpL.process (hpL.high);
|
||||
|
||||
hpR.setG (gLow);
|
||||
hpR.process (inR);
|
||||
lpR.setG (gHigh);
|
||||
lpR.process (hpR.high);
|
||||
|
||||
const float fl = lpL.low;
|
||||
const float fr = lpR.low;
|
||||
|
||||
const float invRt = 1.0f / (rtCur * sizeCur * (float) sampleRate);
|
||||
|
||||
const float loopInvRt = invRt * (1.0f - 0.7f * fbGain);
|
||||
|
||||
const float gMax = std::exp (-6.907755f * baseLen[0] * sizeCur * loopInvRt);
|
||||
|
||||
const float fbL = fl + fbGain * 0.5f * (1.0f - gMax) * shiftL.process (lastWetL, ratio);
|
||||
const float fbR = fr + fbGain * 0.5f * (1.0f - gMax) * shiftR.process (lastWetR, ratio);
|
||||
|
||||
const float dL = diffL2.process (diffL1.process (fbL, diffG), diffG);
|
||||
const float dR = diffR2.process (diffR1.process (fbR, diffG), diffG);
|
||||
|
||||
float wetL = 0.0f;
|
||||
float wetR = 0.0f;
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
const float lenL = baseLen[(size_t) i] * sizeCur;
|
||||
const float gainL = std::exp (-6.907755f * lenL * loopInvRt);
|
||||
wetL += 0.25f * combL[(size_t) i].process (dL, lenL, dampC, gainL);
|
||||
|
||||
const float lenR = baseLenR[(size_t) i] * sizeCur;
|
||||
const float gainR = std::exp (-6.907755f * lenR * loopInvRt);
|
||||
wetR += 0.25f * combR[(size_t) i].process (dR, lenR, dampC, gainR);
|
||||
}
|
||||
|
||||
wetL = dcL.process (wetL);
|
||||
wetR = dcR.process (wetR);
|
||||
|
||||
wetL = std::tanh (wetL);
|
||||
wetR = std::tanh (wetR);
|
||||
|
||||
lastWetL = wetL;
|
||||
lastWetR = wetR;
|
||||
|
||||
outL = inL * (1.0f - wetVal) + wetL * wetVal;
|
||||
outR = inR * (1.0f - wetVal) + wetR * wetVal;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue