Tizen 2.1 base
[external/freealut.git] / src / alutCodec.c
1 #include "alutInternal.h"
2
3 ALvoid *
4 _alutCodecLinear (ALvoid *data, size_t length, ALint numChannels,
5                   ALint bitsPerSample, ALfloat sampleFrequency)
6 {
7   return _alutBufferDataConstruct (data, length, numChannels, bitsPerSample,
8                                    sampleFrequency);
9 }
10
11 ALvoid *
12 _alutCodecPCM8s (ALvoid *data, size_t length, ALint numChannels,
13                  ALint bitsPerSample, ALfloat sampleFrequency)
14 {
15   int8_t *d = (int8_t *) data;
16   size_t i;
17   for (i = 0; i < length; i++)
18     {
19       d[i] += (int8_t) 128;
20     }
21   return _alutBufferDataConstruct (data, length, numChannels, bitsPerSample,
22                                    sampleFrequency);
23 }
24
25 ALvoid *
26 _alutCodecPCM16 (ALvoid *data, size_t length, ALint numChannels,
27                  ALint bitsPerSample, ALfloat sampleFrequency)
28 {
29   int16_t *d = (int16_t *) data;
30   size_t i, l = length / 2;
31   for (i = 0; i < l; i++)
32     {
33       int16_t x = d[i];
34       d[i] = ((x << 8) & 0xFF00) | ((x >> 8) & 0x00FF);
35     }
36   return _alutBufferDataConstruct (data, length, numChannels, bitsPerSample,
37                                    sampleFrequency);
38 }
39
40 /*
41  * From: http://www.multimedia.cx/simpleaudio.html#tth_sEc6.1
42  */
43 static int16_t
44 mulaw2linear (uint8_t mulawbyte)
45 {
46   static const int16_t exp_lut[8] = {
47     0, 132, 396, 924, 1980, 4092, 8316, 16764
48   };
49   int16_t sign, exponent, mantissa, sample;
50   mulawbyte = ~mulawbyte;
51   sign = (mulawbyte & 0x80);
52   exponent = (mulawbyte >> 4) & 0x07;
53   mantissa = mulawbyte & 0x0F;
54   sample = exp_lut[exponent] + (mantissa << (exponent + 3));
55   if (sign != 0)
56     {
57       sample = -sample;
58     }
59   return sample;
60 }
61
62 ALvoid *
63 _alutCodecULaw (ALvoid *data, size_t length, ALint numChannels,
64                 ALint bitsPerSample, ALfloat sampleFrequency)
65 {
66   uint8_t *d = (uint8_t *) data;
67   int16_t *buf = (int16_t *) _alutMalloc (length * 2);
68   size_t i;
69   if (buf == NULL)
70     {
71       return NULL;
72     }
73   for (i = 0; i < length; i++)
74     {
75       buf[i] = mulaw2linear (d[i]);
76     }
77   free (data);
78   return _alutBufferDataConstruct (buf, length * 2, numChannels,
79                                    bitsPerSample, sampleFrequency);
80 }
81
82 /*
83  * From: http://www.multimedia.cx/simpleaudio.html#tth_sEc6.1
84  */
85 #define SIGN_BIT (0x80)         /* Sign bit for a A-law byte. */
86 #define QUANT_MASK (0xf)        /* Quantization field mask. */
87 #define SEG_SHIFT (4)           /* Left shift for segment number. */
88 #define SEG_MASK (0x70)         /* Segment field mask. */
89 static int16_t
90 alaw2linear (uint8_t a_val)
91 {
92   int16_t t, seg;
93   a_val ^= 0x55;
94   t = (a_val & QUANT_MASK) << 4;
95   seg = ((int16_t) a_val & SEG_MASK) >> SEG_SHIFT;
96   switch (seg)
97     {
98     case 0:
99       t += 8;
100       break;
101     case 1:
102       t += 0x108;
103       break;
104     default:
105       t += 0x108;
106       t <<= seg - 1;
107     }
108   return (a_val & SIGN_BIT) ? t : -t;
109 }
110
111 ALvoid *
112 _alutCodecALaw (ALvoid *data, size_t length, ALint numChannels,
113                 ALint bitsPerSample, ALfloat sampleFrequency)
114 {
115   uint8_t *d = (uint8_t *) data;
116   int16_t *buf = (int16_t *) _alutMalloc (length * 2);
117   size_t i;
118   if (buf == NULL)
119     {
120       return NULL;
121     }
122   for (i = 0; i < length; i++)
123     {
124       buf[i] = alaw2linear (d[i]);
125     }
126   free (data);
127   return _alutBufferDataConstruct (buf, length * 2, numChannels,
128                                    bitsPerSample, sampleFrequency);
129 }