Born on Stahl's Birthday.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

114 lines
3.8 KiB

#include "density.hh"
namespace Heck {
namespace Constants {
constexpr Samplerate AUDIO_SAMPLERATE = Samplerate::SAI_48KHZ;
}
void Density::process(const float *inSourceP, float *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