48 lines
1.1 KiB
C++
48 lines
1.1 KiB
C++
#pragma once
|
|
#include <cstdint>
|
|
|
|
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<uint8_t>(0x7f ^ mask);
|
|
else {
|
|
uval = static_cast<uint8_t>((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
|