blob: a467acf3ff7226c54a2f1839d7bf383d67349c80 [file] [log] [blame]
Chia-chi Yeh78c11b32010-09-29 05:46:19 +08001/*
2 * Copyrightm (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "AudioCodec.h"
18
19namespace {
20
Chia-chi Yeh21ae1ad2010-09-30 16:07:44 +080021const int8_t gExponents[128] = {
Chia-chi Yeh78c11b32010-09-29 05:46:19 +080022 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
23 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
24 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
25 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
26 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
27 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
28 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
29 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
30};
31
32//------------------------------------------------------------------------------
33
34class UlawCodec : public AudioCodec
35{
36public:
37 int set(int sampleRate, const char *fmtp) {
38 mSampleCount = sampleRate / 50;
39 return mSampleCount;
40 }
41 int encode(void *payload, int16_t *samples);
42 int decode(int16_t *samples, void *payload, int length);
43private:
44 int mSampleCount;
45};
46
47int UlawCodec::encode(void *payload, int16_t *samples)
48{
49 int8_t *ulaws = (int8_t *)payload;
50 for (int i = 0; i < mSampleCount; ++i) {
51 int sample = samples[i];
52 int sign = (sample >> 8) & 0x80;
53 if (sample < 0) {
54 sample = -sample;
55 }
56 sample += 132;
57 if (sample > 32767) {
58 sample = 32767;
59 }
60 int exponent = gExponents[sample >> 8];
61 int mantissa = (sample >> (exponent + 3)) & 0x0F;
62 ulaws[i] = ~(sign | (exponent << 4) | mantissa);
63 }
64 return mSampleCount;
65}
66
67int UlawCodec::decode(int16_t *samples, void *payload, int length)
68{
69 int8_t *ulaws = (int8_t *)payload;
70 for (int i = 0; i < length; ++i) {
71 int ulaw = ~ulaws[i];
72 int exponent = (ulaw >> 4) & 0x07;
73 int mantissa = ulaw & 0x0F;
74 int sample = (((mantissa << 3) + 132) << exponent) - 132;
75 samples[i] = (ulaw < 0 ? -sample : sample);
76 }
77 return length;
78}
79
80//------------------------------------------------------------------------------
81
82class AlawCodec : public AudioCodec
83{
84public:
85 int set(int sampleRate, const char *fmtp) {
86 mSampleCount = sampleRate / 50;
87 return mSampleCount;
88 }
89 int encode(void *payload, int16_t *samples);
90 int decode(int16_t *samples, void *payload, int length);
91private:
92 int mSampleCount;
93};
94
95int AlawCodec::encode(void *payload, int16_t *samples)
96{
97 int8_t *alaws = (int8_t *)payload;
98 for (int i = 0; i < mSampleCount; ++i) {
99 int sample = samples[i];
100 int sign = (sample >> 8) & 0x80;
101 if (sample < 0) {
102 sample = -sample;
103 }
104 if (sample > 32767) {
105 sample = 32767;
106 }
107 int exponent = gExponents[sample >> 8];
108 int mantissa = (sample >> (exponent == 0 ? 4 : exponent + 3)) & 0x0F;
109 alaws[i] = (sign | (exponent << 4) | mantissa) ^ 0xD5;
110 }
111 return mSampleCount;
112}
113
114int AlawCodec::decode(int16_t *samples, void *payload, int length)
115{
116 int8_t *alaws = (int8_t *)payload;
117 for (int i = 0; i < length; ++i) {
118 int alaw = alaws[i] ^ 0x55;
119 int exponent = (alaw >> 4) & 0x07;
120 int mantissa = alaw & 0x0F;
121 int sample = (exponent == 0 ? (mantissa << 4) + 8 :
122 ((mantissa << 3) + 132) << exponent);
123 samples[i] = (alaw < 0 ? sample : -sample);
124 }
125 return length;
126}
127
128} // namespace
129
130AudioCodec *newUlawCodec()
131{
132 return new UlawCodec;
133}
134
135AudioCodec *newAlawCodec()
136{
137 return new AlawCodec;
138}