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
80
Source/PitchShifter.cpp
Normal file
80
Source/PitchShifter.cpp
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#include "PitchShifter.h"
|
||||
|
||||
#include <JuceHeader.h>
|
||||
|
||||
void PitchShifter::prepare (double sampleRate)
|
||||
{
|
||||
window = (float) std::max (256.0, sampleRate * 0.035);
|
||||
baseDelay = window;
|
||||
bufferSize = (int) (baseDelay + window + 16.0f);
|
||||
buffer.assign ((size_t) bufferSize, 0.0f);
|
||||
writePos = 0;
|
||||
o = 0.0f;
|
||||
}
|
||||
|
||||
void PitchShifter::reset()
|
||||
{
|
||||
std::fill (buffer.begin(), buffer.end(), 0.0f);
|
||||
writePos = 0;
|
||||
o = 0.0f;
|
||||
}
|
||||
|
||||
float PitchShifter::at (int index) const
|
||||
{
|
||||
index %= bufferSize;
|
||||
if (index < 0)
|
||||
index += bufferSize;
|
||||
|
||||
return buffer[(size_t) index];
|
||||
}
|
||||
|
||||
float PitchShifter::readCubic (float pos) const
|
||||
{
|
||||
const int i = (int) std::floor (pos);
|
||||
const float frac = pos - (float) i;
|
||||
|
||||
const float x0 = at (i - 1);
|
||||
const float x1 = at (i);
|
||||
const float x2 = at (i + 1);
|
||||
const float x3 = at (i + 2);
|
||||
|
||||
const float a0 = -0.5f * x0 + 1.5f * x1 - 1.5f * x2 + 0.5f * x3;
|
||||
const float a1 = x0 - 2.5f * x1 + 2.0f * x2 - 0.5f * x3;
|
||||
const float a2 = -0.5f * x0 + 0.5f * x2;
|
||||
const float a3 = x1;
|
||||
|
||||
return ((a0 * frac + a1) * frac + a2) * frac + a3;
|
||||
}
|
||||
|
||||
float PitchShifter::process (float input, float ratio)
|
||||
{
|
||||
buffer[(size_t) writePos] = input;
|
||||
|
||||
if (std::fabs (ratio - 1.0f) < 1e-4f)
|
||||
return input;
|
||||
|
||||
const float theta = juce::MathConstants<float>::pi * o / window;
|
||||
const float g1 = std::sin (theta) * std::sin (theta);
|
||||
const float g2 = std::cos (theta) * std::cos (theta);
|
||||
|
||||
float o2 = o + window * 0.5f;
|
||||
if (o2 >= window)
|
||||
o2 -= window;
|
||||
|
||||
const float pos1 = (float) writePos - (baseDelay - o);
|
||||
const float pos2 = (float) writePos - (baseDelay - o2);
|
||||
|
||||
const float result = g1 * readCubic (pos1) + g2 * readCubic (pos2);
|
||||
|
||||
o += (ratio - 1.0f);
|
||||
if (o >= window)
|
||||
o -= window;
|
||||
else if (o < 0.0f)
|
||||
o += window;
|
||||
|
||||
++writePos;
|
||||
if (writePos >= bufferSize)
|
||||
writePos = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue