Various Datatypes.
[AROS-Contrib.git] / workbench / classes / datatypes / au / au_alaw.c
blob639a1a644cc8b451d7513c324b989877e5751225
1 /*
2 * sun_au.datatype by Fredrik Wikstrom
4 */
6 #include "au_class.h"
7 #include "au_format.h"
8 #include "au_alaw.h"
10 static int16 decode_alaw (uint8 a_val);
11 static int16 decode_mulaw(uint8 u_val);
13 DEC_SETUPPROTO(SetupALAW) {
14 data->sample.size = 1;
15 data->block.size = data->sample.size * data->au.channels;
16 data->block.frames = 1;
17 return OK;
20 DECODERPROTO(DecodeALAW) {
21 int32 fr, ch;
22 for (fr = 0; fr < numFrames; fr++) {
23 for (ch = 0; ch < data->au.channels; ch++) {
24 *Dst[ch]++ = decode_alaw(*Src++) >> 8;
27 return frameIndex + numFrames;
30 DECODERPROTO(DecodeULAW) {
31 int32 fr, ch;
32 for (fr = 0; fr < numFrames; fr++) {
33 for (ch = 0; ch < data->au.channels; ch++) {
34 *Dst[ch]++ = decode_mulaw(*Src++) >> 8;
37 return frameIndex + numFrames;
40 #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
41 #define QUANT_MASK (0xf) /* Quantization field mask. */
42 #define SEG_SHIFT (4) /* Left shift for segment number. */
43 #define SEG_MASK (0x70) /* Segment field mask. */
44 #define BIAS (0x84) /* Bias for linear code. */
46 static int16 decode_alaw (uint8 a_val) {
47 int16 t;
48 int16 seg;
50 a_val ^= 0x55;
52 t = (a_val & QUANT_MASK) << 4;
53 seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
54 switch (seg) {
55 case 0:
56 t += 8;
57 break;
58 case 1:
59 t += 0x108;
60 break;
61 default:
62 t += 0x108;
63 t <<= seg - 1;
65 return ((a_val & SIGN_BIT) ? t : -t);
68 static int16 decode_mulaw(uint8 u_val) {
69 int16 t;
71 /* Complement to obtain normal u-law value. */
72 u_val = ~u_val;
75 * Extract and bias the quantization bits. Then
76 * shift up by the segment number and subtract out the bias.
78 t = ((u_val & QUANT_MASK) << 3) + BIAS;
79 t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
81 return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));