44 lines
1.0 KiB
C
44 lines
1.0 KiB
C
#define BIAS (0x84) /* Bias for linear code. */
|
|
|
|
static int search(int val, short* table, int size)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < size; i++) {
|
|
if (val <= *table++)
|
|
return (i);
|
|
}
|
|
return (size);
|
|
}
|
|
|
|
static short seg_end[8] = { 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF };
|
|
|
|
unsigned char linear2ulaw(int pcm_val) /* 2's complement (16-bit range) */
|
|
{
|
|
int mask;
|
|
int seg;
|
|
unsigned char uval;
|
|
|
|
/* Get the sign and the magnitude of the value. */
|
|
if (pcm_val < 0) {
|
|
pcm_val = BIAS - pcm_val;
|
|
mask = 0x7F;
|
|
} else {
|
|
pcm_val += BIAS;
|
|
mask = 0xFF;
|
|
}
|
|
|
|
/* Convert the scaled magnitude to segment number. */
|
|
seg = search(pcm_val, seg_end, 8);
|
|
|
|
/*
|
|
* Combine the sign, segment, quantization bits;
|
|
* and complement the code word.
|
|
*/
|
|
if (seg >= 8) /* out of range, return maximum value. */
|
|
return (0x7F ^ mask);
|
|
else {
|
|
uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
|
|
return (uval ^ mask);
|
|
}
|
|
} |