noisecraft
noisecraft copied to clipboard
Bitcrush
Per #81.
Let me know what you think of it so far :)
I like that you've added tests.
I actually implemented the bit depth reduction for my own variant and this is the code I had:
// Clamp the input in the [-1, 1] range
inVal = Math.max(Math.min(inVal, 1), -1);
// Map the input to the [0, INT16_MAX] range
let intVal = Math.floor(65535 * (1 + inVal) / 2);
// Drop the bits we don't need
intVal = intVal >> (16 - numBits);
// Convert the value to a floating point number
let maxVal = (1 << numBits) - 1;
let floatVal = intVal / maxVal;
let outVal = floatVal * 2 - 1;
I think we need a bit depth of 32 to signify no bit depth reduction, and the sample rate reduction is probably more useful in terms of how it sounds.
implemented the bit depth reduction for my own variant and this is the code I had:
Very cool. Our approaches are slightly different which I can illustrate when we move to a low number of bits - let's start with 1 bit. At one bit, your algorithm pushes the output to the boundaries at -1 and 1. My algorithm has the +qDelta factor which means it outputs -0.5 and 0.5 (you can see this in the unit tests).
In other words, with 1 bit, your algo chops the space into one segment with outputs at top of bottom. My algo divides the space into two segments and outputs the average level for each segment. I don't know which method would output less error on average, nor which would sound better. Either seems to work.
I just added in sample rate scaling as well - ptal.
The feature has a flag useAvg
which toggles between using an average value (and thus delay be 'factor' samples) or a held value from the input (no averaging).
From the limited audio tests I ran, averaging sounded better but probably also depends on the case at hand.
Unit tests for this still tbd.
Hello Greg. Sorry for the slow response, got busy with life. I've tried the PR and added comments.
No problem. I'm also busy this week and probably won't have time to resolve until the weekend at best.