Browse Source

libDizzy: Add module 'density'

usb_midi_launchpad
heck 6 months ago
parent
commit
2e00ffbeba
  1. 110
      src/density.cc
  2. 33
      src/density.hh

110
src/density.cc

@ -0,0 +1,110 @@
#include "density.hh"
namespace Heck {
void Density::process(const f32 *inSourceP, f32 *inDestP, u32 size)
{
UInt32 nSampleFrames = size;
const Float32 *sourceP = inSourceP;
Float32 *destP = inDestP;
Float64 inputSample;
Float64 drySample;
Float64 overallscale = 1.0;
overallscale /= 44100.0;
overallscale *= Constants::AUDIO_SAMPLERATE;
Float64 density = params[0];
Float64 iirAmount = pow(params[1], 3) / overallscale;
Float64 output = params[2];
Float64 wet = params[3];
Float64 dry = 1.0 - wet;
Float64 bridgerectifier;
Float64 out = fabs(density);
density = density * fabs(density);
Float64 count;
while (nSampleFrames-- > 0) {
inputSample = *sourceP;
if (fabs(inputSample) < 1.18e-23) {
inputSample = fpd * 1.18e-17;
}
drySample = inputSample;
if (fpFlip) {
iirSampleA = (iirSampleA * (1 - iirAmount)) + (inputSample * iirAmount);
inputSample -= iirSampleA;
} else {
iirSampleB = (iirSampleB * (1 - iirAmount)) + (inputSample * iirAmount);
inputSample -= iirSampleB;
}
//highpass section
count = density;
while (count > 1.0) {
bridgerectifier = fabs(inputSample) * 1.57079633;
if (bridgerectifier > 1.57079633) {
bridgerectifier = 1.57079633;
}
//max value for sine function
bridgerectifier = sin(bridgerectifier);
if (inputSample > 0.0) {
inputSample = bridgerectifier;
} else {
inputSample = -bridgerectifier;
}
count = count - 1.0;
}
//we have now accounted for any really high density settings.
while (out > 1.0) {
out = out - 1.0;
}
bridgerectifier = fabs(inputSample) * 1.57079633;
if (bridgerectifier > 1.57079633) {
bridgerectifier = 1.57079633;
}
//max value for sine function
if (density > 0) {
bridgerectifier = sin(bridgerectifier);
} else {
bridgerectifier = 1 - cos(bridgerectifier);
}
//produce either boosted or starved version
if (inputSample > 0) {
inputSample = (inputSample * (1 - out)) + (bridgerectifier * out);
} else {
inputSample = (inputSample * (1 - out)) - (bridgerectifier * out);
}
//blend according to density control
if (output < 1.0) {
inputSample *= output;
}
if (wet < 1.0) {
inputSample = (drySample * dry) + (inputSample * wet);
}
//nice little output stage template: if we have another scale of floating point
//number, we really don't want to meaninglessly multiply that by 1.0.
fpFlip = !fpFlip;
//begin 32 bit floating point dither
if constexpr (DO_DITHER) {
int expon;
frexpf((float)inputSample, &expon);
fpd ^= fpd << 13;
fpd ^= fpd >> 17;
fpd ^= fpd << 5;
inputSample += ((double(fpd) - uint32_t(0x7fffffff)) * 5.5e-36l * pow(2, expon + 62));
//end 32 bit floating point dither
}
*destP = inputSample;
//that simple.
sourceP++;
destP++;
}
}
} // namespace Heck

33
src/density.hh

@ -0,0 +1,33 @@
#ifndef HECK_OSP_DENSITY
#define HECK_OSP_DENSITY
#include "types.hh"
#include <array>
namespace Heck::Constants {
constexpr Samplerate AUDIO_SAMPLERATE = Samplerate::SAI_48KHZ;
}
namespace Heck {
struct Density {
using Float32 = f32;
using Float64 = f64;
using UInt32 = u32;
static constexpr bool DO_DITHER{ false };
std::array<f64, 4> params{ 0., 0., 1., 1. };
void process(const f32 * const inSourceP, f32 *inDestP, u32 size);
private:
Float64 iirSampleA;
Float64 iirSampleB;
uint32_t fpd;
bool fpFlip;
};
} // namespace Heck
#endif
Loading…
Cancel
Save