2 changed files with 143 additions and 0 deletions
@ -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
|
@ -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…
Reference in new issue