Skip to content
15 changes: 5 additions & 10 deletions DSP/AllpassDiffuser.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ THE SOFTWARE.

#pragma once

#include <vector>
#include "ModulatedAllpass.h"
#include "RandomBuffer.h"

Expand All @@ -31,15 +30,15 @@ namespace Cloudseed
class AllpassDiffuser
{
public:
static const int MaxStageCount = 12;
static constexpr int MaxStageCount = 12;

private:
int samplerate;

ModulatedAllpass filters[MaxStageCount];
int delay;
float modRate;
std::vector<float> seedValues;
float seedValues[MaxStageCount * 3];
int seed;
float crossSeed;

Expand Down Expand Up @@ -126,14 +125,10 @@ namespace Cloudseed

void Process(float* input, float* output, int bufSize)
{
float tempBuffer[BUFFER_SIZE];

filters[0].Process(input, tempBuffer, bufSize);
filters[0].Process(input, output, bufSize);

for (int i = 1; i < Stages; i++)
filters[i].Process(tempBuffer, tempBuffer, bufSize);

Utils::Copy(output, tempBuffer, bufSize);
filters[i].Process(output, output, bufSize);
}

void ClearBuffers()
Expand All @@ -155,7 +150,7 @@ namespace Cloudseed

void UpdateSeeds()
{
this->seedValues = RandomBuffer::Generate(seed, MaxStageCount * 3, crossSeed);
RandomBuffer::Generate(seed, seedValues, MaxStageCount * 3, crossSeed);
Update();
}

Expand Down
4 changes: 2 additions & 2 deletions DSP/DelayLine.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ namespace Cloudseed

void Reset()
{
for (int i = 0; i < N; i++)
buffer[i] = 0.0f;
memset(buffer, 0, sizeof buffer);

idxRead = 0;
idxWrite = 0;
count = 0;
Expand Down
10 changes: 3 additions & 7 deletions DSP/LcgRandom.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,16 @@ namespace Cloudseed
uint64_t a;
uint64_t c;

double doubleInv;
float floatUintInv;
float floatIntInv;
static constexpr double doubleInv = 1.0 / UINT32_MAX;
static constexpr float floatUintInv = 1.0 / UINT32_MAX;
static constexpr float floatIntInv = 1.0 / INT32_MAX;

public:
inline LcgRandom(uint64_t seed = 0)
{
x = seed;
a = 22695477;
c = 1;

doubleInv = 1.0 / (double)UINT32_MAX;
floatUintInv = 1.0 / (float)UINT32_MAX;
floatIntInv = 1.0 / (float)INT32_MAX;
}

inline void SetSeed(uint64_t seed)
Expand Down
12 changes: 4 additions & 8 deletions DSP/ModulatedAllpass.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ namespace Cloudseed
class ModulatedAllpass
{
public:
static const int DelayBufferSize = 19200; // 100ms at 192Khz
static const int ModulationUpdateRate = 8;
static constexpr int DelayBufferSize = 19200; // 100ms at 192Khz
static constexpr int ModulationUpdateRate = 8;

private:
float delayBuffer[DelayBufferSize] = { 0 };
Expand Down Expand Up @@ -161,20 +161,16 @@ namespace Cloudseed
void Update()
{
modPhase += ModRate * ModulationUpdateRate;
if (modPhase > 1)
modPhase = std::fmod(modPhase, 1.0);
if (modPhase > 1.0f)
modPhase -= (int)modPhase;

auto mod = std::sinf(modPhase * 2 * M_PI);

if (ModAmount >= SampleDelay) // don't modulate to negative value
ModAmount = SampleDelay - 1;


auto totalDelay = SampleDelay + ModAmount * mod;

if (totalDelay <= 0) // should no longer be required
totalDelay = 1;

delayA = (int)totalDelay;
delayB = (int)totalDelay + 1;

Expand Down
8 changes: 4 additions & 4 deletions DSP/ModulatedDelay.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ namespace Cloudseed
{
private:

static const int ModulationUpdateRate = 8;
static const int DelayBufferSize = 192000 * 2;
static constexpr int ModulationUpdateRate = 8;
static constexpr int DelayBufferSize = 192000 * 2;

float delayBuffer[DelayBufferSize] = { 0 };
int writeIndex;
Expand Down Expand Up @@ -102,8 +102,8 @@ namespace Cloudseed
void Update()
{
modPhase += ModRate * ModulationUpdateRate;
if (modPhase > 1)
modPhase = std::fmod(modPhase, 1.0);
if (modPhase > 1.0f)
modPhase -= (int)modPhase;

auto mod = std::sinf(modPhase * 2 * M_PI);
auto totalDelay = SampleDelay + ModAmount * mod;
Expand Down
11 changes: 4 additions & 7 deletions DSP/MultitapDelay.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ THE SOFTWARE.

#pragma once

#include <vector>
#include <memory>
#include <array>
#include <cmath>
#include "Utils.h"
#include "RandomBuffer.h"
Expand All @@ -34,16 +31,16 @@ namespace Cloudseed
class MultitapDelay
{
public:
static const int MaxTaps = 256;
static const int DelayBufferSize = 192000 * 2;
static constexpr int MaxTaps = 256;
static constexpr int DelayBufferSize = 192000 * 2;

private:
float delayBuffer[DelayBufferSize] = { 0 };

float tapGains[MaxTaps] = { 0 };
float tapPosition[MaxTaps] = { 0 };

std::vector<float> seedValues;
float seedValues[MaxTaps * 3];

int writeIdx;
int seed;
Expand Down Expand Up @@ -143,7 +140,7 @@ namespace Cloudseed

void UpdateSeeds()
{
this->seedValues = RandomBuffer::Generate(seed, MaxTaps * 3, crossSeed);
RandomBuffer::Generate(seed, seedValues, MaxTaps * 3, crossSeed);
Update();
}
};
Expand Down
25 changes: 11 additions & 14 deletions DSP/RandomBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,29 @@ THE SOFTWARE.

namespace Cloudseed
{
std::vector<float> RandomBuffer::Generate(uint64_t seed, int count)
void RandomBuffer::Generate(uint64_t seed, float* output, int count)
{
LcgRandom rand(seed);
std::vector<float> output;

for (int i = 0; i < count; i++)
{
unsigned int val = rand.NextUInt();
float fVal = val / (float)UINT_MAX;
output.push_back(fVal);
output[i] = fVal;
}

return output;
}

std::vector<float> RandomBuffer::Generate(uint64_t seed, int count, float crossSeed)
void RandomBuffer::Generate(uint64_t seed, float* output, int count, float crossSeed)
{
auto seedA = seed;
auto seedB = ~seed;
auto seriesA = Generate(seedA, count);
auto seriesB = Generate(seedB, count);
uint64_t seedA = seed;
uint64_t seedB = ~seed;
float seriesA[count];
float seriesB[count];

std::vector<float> output;
for (int i = 0; i < count; i++)
output.push_back(seriesA[i] * (1 - crossSeed) + seriesB[i] * crossSeed);
Generate(seedA, seriesA, count);
Generate(seedB, seriesB, count);

return output;
for (int i = 0; i < count; i++)
output[i] = seriesA[i] * (1 - crossSeed) + seriesB[i] * crossSeed;
}
}
5 changes: 2 additions & 3 deletions DSP/RandomBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ THE SOFTWARE.

#pragma once

#include <vector>
#include <stdint.h>

namespace Cloudseed
{
class RandomBuffer
{
public:
static std::vector<float> Generate(uint64_t seed, int count);
static std::vector<float> Generate(uint64_t seed, int count, float crossSeed);
static void Generate(uint64_t seed, float* output, int count);
static void Generate(uint64_t seed, float* output, int count, float crossSeed);
};
}
8 changes: 3 additions & 5 deletions DSP/ReverbChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ THE SOFTWARE.

#pragma once

#include <map>
#include <memory>
#include "../Parameters.h"
#include "ModulatedDelay.h"
#include "MultitapDelay.h"
Expand All @@ -47,7 +45,7 @@ namespace Cloudseed
class ReverbChannel
{
private:
static const int TotalLineCount = 12;
static constexpr int TotalLineCount = 12;

double paramsScaled[Parameter::COUNT] = { 0.0 };
int samplerate;
Expand All @@ -56,7 +54,6 @@ namespace Cloudseed
MultitapDelay multitap;
AllpassDiffuser diffuser;
DelayLine lines[TotalLineCount];
RandomBuffer rand;
Hp1 highPass;
Lp1 lowPass;

Expand Down Expand Up @@ -390,7 +387,8 @@ namespace Cloudseed
auto lateDiffusionModAmount = Ms2Samples(paramsScaled[Parameter::LateDiffuseModAmount]);
auto lateDiffusionModRate = paramsScaled[Parameter::LateDiffuseModRate];

auto delayLineSeeds = RandomBuffer::Generate(delayLineSeed, TotalLineCount * 3, crossSeed);
float delayLineSeeds[TotalLineCount * 3];
RandomBuffer::Generate(delayLineSeed, delayLineSeeds, TotalLineCount * 3, crossSeed);

for (int i = 0; i < TotalLineCount; i++)
{
Expand Down
16 changes: 5 additions & 11 deletions DSP/ReverbController.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ THE SOFTWARE.

#pragma once

#include <vector>
#include "../Parameters.h"
#include "ReverbChannel.h"
#include "AllpassDiffuser.h"
Expand Down Expand Up @@ -86,19 +85,14 @@ namespace Cloudseed

void Process(float* inL, float* inR, float* outL, float* outR, int bufSize)
{
float outLTemp[BUFFER_SIZE];
float outRTemp[BUFFER_SIZE];

while (bufSize > 0)
{
int subBufSize = bufSize > BUFFER_SIZE ? BUFFER_SIZE : bufSize;
ProcessChunk(inL, inR, outLTemp, outRTemp, subBufSize);
Utils::Copy(outL, outLTemp, subBufSize);
Utils::Copy(outR, outRTemp, subBufSize);
inL = &inL[subBufSize];
inR = &inR[subBufSize];
outL = &outL[subBufSize];
outR = &outR[subBufSize];
ProcessChunk(inL, inR, outL, outR, subBufSize);
inL += subBufSize;
inR += subBufSize;
outL += subBufSize;
outR += subBufSize;
bufSize -= subBufSize;
}
}
Expand Down
60 changes: 30 additions & 30 deletions DSP/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,54 +59,54 @@ namespace Cloudseed
target[i] += source[i] * gain;
}

inline float DB2Gainf(float input)
inline constexpr float DB2Gainf(float input)
{
//return std::pow(10.0f, input / 20.0f);
return powf(10, input * 0.05f);
}

template<typename T>
inline double DB2Gain(T input)
inline constexpr double DB2Gain(T input)
{
return pow10f(input / 20.0);
}

template<typename T>
inline double Gain2DB(T input)
inline constexpr double Gain2DB(T input)
{
//if (input < 0.0000001)
// return -100000;

return 20.0f * log10f(input);
}

const float dec1Mult = (10 / 9.0) * 0.1;
const float dec2Mult = (100 / 99.0) * 0.01;
const float dec3Mult = (1000 / 999.0) * 0.001;
const float dec4Mult = (10000 / 9999.0) * 0.0001;

const float oct1Mult = (2 / 1.0) * 0.5;
const float oct2Mult = (4 / 3.0) * 0.25;
const float oct3Mult = (8 / 7.0) * 0.125;
const float oct4Mult = (16 / 15.0) * 0.0625;
const float oct5Mult = (32 / 31.0) * 0.03125;
const float oct6Mult = (64 / 63.0) * 0.015625;
const float oct7Mult = (128 / 127.0) * 0.0078125;
const float oct8Mult = (256 / 255.0) * 0.00390625;

inline float Resp1dec(float x) { return (powf(10, x) - 1) * dec1Mult; }
inline float Resp2dec(float x) { return (powf(10, 2 * x) - 1) * dec2Mult; }
inline float Resp3dec(float x) { return (powf(10, 3 * x) - 1) * dec3Mult; }
inline float Resp4dec(float x) { return (powf(10, 4 * x) - 1) * dec4Mult; }

inline float Resp1oct(float x) { return (powf(2, x) - 1) * oct1Mult; }
inline float Resp2oct(float x) { return (powf(2, 2 * x) - 1) * oct2Mult; }
inline float Resp3oct(float x) { return (powf(2, 3 * x) - 1) * oct3Mult; }
inline float Resp4oct(float x) { return (powf(2, 4 * x) - 1) * oct4Mult; }
inline float Resp5oct(float x) { return (powf(2, 5 * x) - 1) * oct5Mult; }
inline float Resp6oct(float x) { return (powf(2, 6 * x) - 1) * oct6Mult; }
inline float Resp7oct(float x) { return (powf(2, 7 * x) - 1) * oct7Mult; }
inline float Resp8oct(float x) { return (powf(2, 8 * x) - 1) * oct8Mult; }
constexpr float dec1Mult = (10 / 9.0) * 0.1;
constexpr float dec2Mult = (100 / 99.0) * 0.01;
constexpr float dec3Mult = (1000 / 999.0) * 0.001;
constexpr float dec4Mult = (10000 / 9999.0) * 0.0001;

constexpr float oct1Mult = (2 / 1.0) * 0.5;
constexpr float oct2Mult = (4 / 3.0) * 0.25;
constexpr float oct3Mult = (8 / 7.0) * 0.125;
constexpr float oct4Mult = (16 / 15.0) * 0.0625;
constexpr float oct5Mult = (32 / 31.0) * 0.03125;
constexpr float oct6Mult = (64 / 63.0) * 0.015625;
constexpr float oct7Mult = (128 / 127.0) * 0.0078125;
constexpr float oct8Mult = (256 / 255.0) * 0.00390625;

inline constexpr float Resp1dec(float x) { return (powf(10, x) - 1) * dec1Mult; }
inline constexpr float Resp2dec(float x) { return (powf(10, 2 * x) - 1) * dec2Mult; }
inline constexpr float Resp3dec(float x) { return (powf(10, 3 * x) - 1) * dec3Mult; }
inline constexpr float Resp4dec(float x) { return (powf(10, 4 * x) - 1) * dec4Mult; }

inline constexpr float Resp1oct(float x) { return (powf(2, x) - 1) * oct1Mult; }
inline constexpr float Resp2oct(float x) { return (powf(2, 2 * x) - 1) * oct2Mult; }
inline constexpr float Resp3oct(float x) { return (powf(2, 3 * x) - 1) * oct3Mult; }
inline constexpr float Resp4oct(float x) { return (powf(2, 4 * x) - 1) * oct4Mult; }
inline constexpr float Resp5oct(float x) { return (powf(2, 5 * x) - 1) * oct5Mult; }
inline constexpr float Resp6oct(float x) { return (powf(2, 6 * x) - 1) * oct6Mult; }
inline constexpr float Resp7oct(float x) { return (powf(2, 7 * x) - 1) * oct7Mult; }
inline constexpr float Resp8oct(float x) { return (powf(2, 8 * x) - 1) * oct8Mult; }

}
}