diff --git a/companding/alaw.h b/companding/alaw.h new file mode 100644 index 0000000..d1cd9fa --- /dev/null +++ b/companding/alaw.h @@ -0,0 +1,38 @@ +#pragma once + +#include + +namespace trnr { + +constexpr float A_LAW_A = 87.6f; + +inline float alaw_encode(float input) +{ + float sign = (input >= 0.0f) ? 1.0f : -1.0f; + float abs_sample = std::fabs(input); + + float output; + if (abs_sample < (1.0f / A_LAW_A)) { + output = sign * (A_LAW_A * abs_sample) / (1.0f + std::log(A_LAW_A)); + } else { + output = sign * (1.0f + std::log(A_LAW_A * abs_sample)) / (1.0f + std::log(A_LAW_A)); + } + + return output; +} + +inline float alaw_decode(float input) +{ + float sign = (input >= 0.0f) ? 1.0f : -1.0f; + float abs_comp = std::fabs(input); + + float sample; + if (abs_comp < (1.0f / (1.0f + std::log(A_LAW_A)))) { + sample = sign * (abs_comp * (1.0f + std::log(A_LAW_A))) / A_LAW_A; + } else { + sample = sign * std::exp(abs_comp * (1.0f + std::log(A_LAW_A)) - 1.0f) / A_LAW_A; + } + + return sample; +} +} // namespace trnr \ No newline at end of file diff --git a/companding/mulaw.h b/companding/mulaw.h deleted file mode 100644 index 78aeb70..0000000 --- a/companding/mulaw.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once -#include - -namespace trnr { -// mulaw companding based on code by Emilie Gillet / Mutable Instruments -class mulaw { -public: - int8_t encode_samples(int16_t pcm_val) - { - int16_t mask; - int16_t seg; - uint8_t uval; - pcm_val = pcm_val >> 2; - if (pcm_val < 0) { - pcm_val = -pcm_val; - mask = 0x7f; - } else { - mask = 0xff; - } - if (pcm_val > 8159) pcm_val = 8159; - pcm_val += (0x84 >> 2); - - if (pcm_val <= 0x3f) seg = 0; - else if (pcm_val <= 0x7f) seg = 1; - else if (pcm_val <= 0xff) seg = 2; - else if (pcm_val <= 0x1ff) seg = 3; - else if (pcm_val <= 0x3ff) seg = 4; - else if (pcm_val <= 0x7ff) seg = 5; - else if (pcm_val <= 0xfff) seg = 6; - else if (pcm_val <= 0x1fff) seg = 7; - else seg = 8; - if (seg >= 8) return static_cast(0x7f ^ mask); - else { - uval = static_cast((seg << 4) | ((pcm_val >> (seg + 1)) & 0x0f)); - return (uval ^ mask); - } - } - - int16_t decode_samples(uint8_t u_val) - { - int16_t t; - u_val = ~u_val; - t = ((u_val & 0xf) << 3) + 0x84; - t <<= ((unsigned)u_val & 0x70) >> 4; - return ((u_val & 0x80) ? (0x84 - t) : (t - 0x84)); - } -}; -} // namespace trnr \ No newline at end of file diff --git a/companding/ulaw.h b/companding/ulaw.h deleted file mode 100644 index 4b920c9..0000000 --- a/companding/ulaw.h +++ /dev/null @@ -1,108 +0,0 @@ -#pragma once -#include -#include -#include - -namespace trnr { -// ulaw compansion based on code by Chris Johnson -class ulaw { -public: - ulaw() - { - fpd_l = 1.0; - while (fpd_l < 16386) fpd_l = rand() * UINT32_MAX; - fpd_r = 1.0; - while (fpd_r < 16386) fpd_r = rand() * UINT32_MAX; - } - - void encode_samples(double& input_sample_l, double& input_sample_r) - { - - // ulaw encoding - static int noisesource_l = 0; - static int noisesource_r = 850010; - int residue; - double applyresidue; - - noisesource_l = noisesource_l % 1700021; - noisesource_l++; - residue = noisesource_l * noisesource_l; - residue = residue % 170003; - residue *= residue; - residue = residue % 17011; - residue *= residue; - residue = residue % 1709; - residue *= residue; - residue = residue % 173; - residue *= residue; - residue = residue % 17; - applyresidue = residue; - applyresidue *= 0.00000001; - applyresidue *= 0.00000001; - input_sample_l += applyresidue; - if (input_sample_l < 1.2e-38 && -input_sample_l < 1.2e-38) { input_sample_l -= applyresidue; } - - noisesource_r = noisesource_r % 1700021; - noisesource_r++; - residue = noisesource_r * noisesource_r; - residue = residue % 170003; - residue *= residue; - residue = residue % 17011; - residue *= residue; - residue = residue % 1709; - residue *= residue; - residue = residue % 173; - residue *= residue; - residue = residue % 17; - applyresidue = residue; - applyresidue *= 0.00000001; - applyresidue *= 0.00000001; - input_sample_r += applyresidue; - if (input_sample_r < 1.2e-38 && -input_sample_r < 1.2e-38) { input_sample_r -= applyresidue; } - - if (input_sample_l > 1.0) input_sample_l = 1.0; - if (input_sample_l < -1.0) input_sample_l = -1.0; - - if (input_sample_r > 1.0) input_sample_r = 1.0; - if (input_sample_r < -1.0) input_sample_r = -1.0; - - if (input_sample_l > 0) input_sample_l = log(1.0 + (255 * fabs(input_sample_l))) / log(256); - if (input_sample_l < 0) input_sample_l = -log(1.0 + (255 * fabs(input_sample_l))) / log(256); - - if (input_sample_r > 0) input_sample_r = log(1.0 + (255 * fabs(input_sample_r))) / log(256); - if (input_sample_r < 0) input_sample_r = -log(1.0 + (255 * fabs(input_sample_r))) / log(256); - } - - void decode_samples(double& input_sample_l, double& input_sample_r) - { - - // ulaw decoding - if (fabs(input_sample_l) < 1.18e-23) input_sample_l = fpd_l * 1.18e-17; - if (fabs(input_sample_r) < 1.18e-23) input_sample_r = fpd_r * 1.18e-17; - - if (input_sample_l > 1.0) input_sample_l = 1.0; - if (input_sample_l < -1.0) input_sample_l = -1.0; - - if (input_sample_r > 1.0) input_sample_r = 1.0; - if (input_sample_r < -1.0) input_sample_r = -1.0; - - if (input_sample_l > 0) input_sample_l = (pow(256, fabs(input_sample_l)) - 1.0) / 255; - if (input_sample_l < 0) input_sample_l = -(pow(256, fabs(input_sample_l)) - 1.0) / 255; - - if (input_sample_r > 0) input_sample_r = (pow(256, fabs(input_sample_r)) - 1.0) / 255; - if (input_sample_r < 0) input_sample_r = -(pow(256, fabs(input_sample_r)) - 1.0) / 255; - - // 64 bit stereo floating point dither - fpd_l ^= fpd_l << 13; - fpd_l ^= fpd_l >> 17; - fpd_l ^= fpd_l << 5; - fpd_r ^= fpd_r << 13; - fpd_r ^= fpd_r >> 17; - fpd_r ^= fpd_r << 5; - } - -private: - uint32_t fpd_l; - uint32_t fpd_r; -}; -} // namespace trnr \ No newline at end of file