From c2c89b6aaa9523d7b5ee99080c3d071de9536956 Mon Sep 17 00:00:00 2001 From: mezmay Date: Wed, 9 Mar 2016 17:06:48 +0300 Subject: [PATCH] files added --- BerVibrato/BerVibrato.cpp | 26 ++++++++++++++++++ BerVibrato/BerVibrato.h | 47 +++++++++++++++++++++++++++++++ BerVibrato/Lfo.cpp | 39 ++++++++++++++++++++++++++ BerVibrato/Lfo.h | 24 ++++++++++++++++ BerVibrato/Ringbuffer.cpp | 43 +++++++++++++++++++++++++++++ BerVibrato/Ringbuffer.h | 58 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 237 insertions(+) create mode 100644 BerVibrato/BerVibrato.cpp create mode 100644 BerVibrato/BerVibrato.h create mode 100644 BerVibrato/Lfo.cpp create mode 100644 BerVibrato/Lfo.h create mode 100644 BerVibrato/Ringbuffer.cpp create mode 100644 BerVibrato/Ringbuffer.h diff --git a/BerVibrato/BerVibrato.cpp b/BerVibrato/BerVibrato.cpp new file mode 100644 index 0000000..e4aa7dd --- /dev/null +++ b/BerVibrato/BerVibrato.cpp @@ -0,0 +1,26 @@ +#include "BerVibrato.h" + +BerVibrato::BerVibrato() +: depth(0) +, sampleRate(0) +{ + setFrequency(VIBRATO_FREQUENCY_DEFAULT_HZ); + setDepth(VIBRATO_DEPTH_DEFAULT_PERCENT / 100); +} + +void BerVibrato::initialize(float sr) +{ + sampleRate = sr; + lfo.initialize(sampleRate, VIBRATO_FREQUENCY_DEFAULT_HZ); + buffer.resize(BASE_DELAY_SEC * sampleRate * 2); +} + +void BerVibrato::setFrequency(float frequency) +{ + lfo.setFrequency(frequency); +} + +void BerVibrato::setDepth(float dt) +{ + depth = dt; +} \ No newline at end of file diff --git a/BerVibrato/BerVibrato.h b/BerVibrato/BerVibrato.h new file mode 100644 index 0000000..c43369a --- /dev/null +++ b/BerVibrato/BerVibrato.h @@ -0,0 +1,47 @@ +#ifndef VIBRATO_PROCESSOR_H +#define VIBRATO_PROCESSOR_H + +#include "Lfo.h" +#include "RingBuffer.h" + +const float BASE_DELAY_SEC = 0.002; // 2 ms +const float VIBRATO_FREQUENCY_DEFAULT_HZ = 2; +const float VIBRATO_FREQUENCY_MAX_HZ = 14; +const float VIBRATO_DEPTH_DEFAULT_PERCENT = 50; + +class BerVibrato +{ +public: + BerVibrato(); + +public: + void initialize(float sampleRate); + void process(float* input, float*output, int numberOfSamples); + void setFrequency(float frequency); + void setDepth(float depth); + +public: + INLINE float processOneSample(float input) + { + float lfoValue = lfo.getValue(); + int maxDelay = BASE_DELAY_SEC * sampleRate; + + float delay = lfoValue * depth * maxDelay; + delay += additionalDelay; + + float value = buffer.getHermiteAt(delay); + + buffer.write_margined(input); + return value; + } + +private: + float sampleRate; + Lfo lfo; + RingBuffer buffer; + float depth; + + static const int additionalDelay = 1; +}; + +#endif \ No newline at end of file diff --git a/BerVibrato/Lfo.cpp b/BerVibrato/Lfo.cpp new file mode 100644 index 0000000..4210278 --- /dev/null +++ b/BerVibrato/Lfo.cpp @@ -0,0 +1,39 @@ +#include "Lfo.h" +#define _USE_MATH_DEFINES +#include /*sin*/ + +Lfo::Lfo() + : index(0), sampleRate(0), frequency(0), phase(0) +{} + +Lfo::~Lfo(void) {} + +void Lfo::initialize(float sr, float freq) +{ + sampleRate = sr; + frequency = freq; +} + +void Lfo::setFrequency(float freq) +{ + frequency = freq; +} + +void Lfo::setPhase(float ph) +{ + phase = ph; +} + +float Lfo::getValue() +{ + const float dp = 2 * M_PI * frequency / sampleRate; // phase step + + float value = sin(phase); + value = (value + 1) * 0.5; // transform from [-1; 1] to [0; 1] + + phase += dp; + while(phase > 2 * M_PI) + phase -= 2 * M_PI; + + return value; +} diff --git a/BerVibrato/Lfo.h b/BerVibrato/Lfo.h new file mode 100644 index 0000000..95ffbf9 --- /dev/null +++ b/BerVibrato/Lfo.h @@ -0,0 +1,24 @@ +#ifndef LFO_H_ +#define LFO_H_ + +class Lfo +{ +public: + Lfo(); + ~Lfo(); + + void initialize(float sampleRate, float freq); + void setFrequency(float freq); + void setPhase(float phase); + +public: + float getValue(); + +private: + float sampleRate; + float frequency; + float phase; + float index; +}; + +#endif \ No newline at end of file diff --git a/BerVibrato/Ringbuffer.cpp b/BerVibrato/Ringbuffer.cpp new file mode 100644 index 0000000..dbc93ea --- /dev/null +++ b/BerVibrato/Ringbuffer.cpp @@ -0,0 +1,43 @@ +#include "RingBuffer.h" + +RingBuffer::RingBuffer() +: size(0), writeIndex(0) +{} + +void RingBuffer::resize(int sz) +{ + size = sz; + buffer.resize(size + interpolatorMargin); +} + +void RingBuffer::write(float sample) +{ + buffer[writeIndex] = sample; + writeIndex++; + if(writeIndex == size){ + writeIndex = 0; + } +} + +void RingBuffer::write_margined(float sample) +{ + buffer[writeIndex] = sample; + + if( writeIndex < interpolatorMargin ) + { + buffer[size + writeIndex] = sample; + } + + writeIndex++; + if(writeIndex == size){ + writeIndex = 0; + } +} + +float RingBuffer::readWithDelay(int delay){ + int readIndex = writeIndex - delay; + if (readIndex < 0){ + readIndex += size; + } + return buffer[readIndex]; +} \ No newline at end of file diff --git a/BerVibrato/Ringbuffer.h b/BerVibrato/Ringbuffer.h new file mode 100644 index 0000000..4e25550 --- /dev/null +++ b/BerVibrato/Ringbuffer.h @@ -0,0 +1,58 @@ +#ifndef __RINGBUFFER_H +#define __RINGBUFFER_H + +#ifdef _MSC_VER +#define INLINE __forceinline +#else +#define INLINE inline +#endif + +#include + +// Hermite polynomial interpolation +INLINE float getSampleHermite4p3o(float x, float *y) +{ + static float c0, c1, c2, c3; + + // 4-point, 3rd-order Hermite (x-form) + c0 = y[1]; + c1 = (1.0/2.0)*(y[2]-y[0]); + c2 = (y[0] - (5.0/2.0)*y[1]) + (2.0*y[2] - (1.0/2.0)*y[3]); + c3 = (1.0/2.0)*(y[3]-y[0]) + (3.0/2.0)*(y[1]-y[2]); + return ((c3*x+c2)*x+c1)*x+c0; +} + +class RingBuffer +{ +public: + RingBuffer(); + + void write(float sample); + void write_margined(float sample); + float readWithDelay(int delay); + void resize(int size); + +public: + INLINE float getHermiteAt(float delay) + { + float fReadIndex = writeIndex - 1 - delay; + while(fReadIndex < 0) + fReadIndex += size; + while(fReadIndex >= size) + fReadIndex -= size; + + int iPart = (int)fReadIndex; // integer part of the delay + float fPart = fReadIndex - iPart; // fractional part of the delay + + return getSampleHermite4p3o(fPart, &(buffer[iPart])); + } + +private: + std::vector buffer; + int writeIndex; + int size; + + static const int interpolatorMargin = 3; +}; + +#endif \ No newline at end of file