1 /*
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 <string.h>
18
19 #include "AudioCodec.h"
20
21 #include "gsmamr_dec.h"
22 #include "gsmamr_enc.h"
23
24 namespace {
25
26 const int gFrameBits[8] = {95, 103, 118, 134, 148, 159, 204, 244};
27
28 //------------------------------------------------------------------------------
29
30 // See RFC 4867 for the encoding details.
31
32 class AmrCodec : public AudioCodec
33 {
34 public:
AmrCodec()35 AmrCodec() {
36 if (AMREncodeInit(&mEncoder, &mSidSync, false)) {
37 mEncoder = NULL;
38 }
39 if (GSMInitDecode(&mDecoder, (Word8 *)"RTP")) {
40 mDecoder = NULL;
41 }
42 }
43
~AmrCodec()44 ~AmrCodec() {
45 if (mEncoder) {
46 AMREncodeExit(&mEncoder, &mSidSync);
47 }
48 if (mDecoder) {
49 GSMDecodeFrameExit(&mDecoder);
50 }
51 }
52
53 int set(int sampleRate, const char *fmtp);
54 int encode(void *payload, int16_t *samples);
55 int decode(int16_t *samples, int count, void *payload, int length);
56
57 private:
58 void *mEncoder;
59 void *mSidSync;
60 void *mDecoder;
61
62 int mMode;
63 int mModeSet;
64 bool mOctetAligned;
65 };
66
set(int sampleRate,const char * fmtp)67 int AmrCodec::set(int sampleRate, const char *fmtp)
68 {
69 // These parameters are not supported.
70 if (strcasestr(fmtp, "crc=1") || strcasestr(fmtp, "robust-sorting=1") ||
71 strcasestr(fmtp, "interleaving=")) {
72 return -1;
73 }
74
75 // Handle mode-set and octet-align.
76 const char *modes = strcasestr(fmtp, "mode-set=");
77 if (modes) {
78 mMode = 0;
79 mModeSet = 0;
80 for (char c = *modes; c && c != ' '; c = *++modes) {
81 if (c >= '0' && c <= '7') {
82 int mode = c - '0';
83 if (mode > mMode) {
84 mMode = mode;
85 }
86 mModeSet |= 1 << mode;
87 }
88 }
89 } else {
90 mMode = 7;
91 mModeSet = 0xFF;
92 }
93 mOctetAligned = (strcasestr(fmtp, "octet-align=1") != NULL);
94
95 // TODO: handle mode-change-*.
96
97 return (sampleRate == 8000 && mEncoder && mDecoder) ? 160 : -1;
98 }
99
encode(void * payload,int16_t * samples)100 int AmrCodec::encode(void *payload, int16_t *samples)
101 {
102 unsigned char *bytes = (unsigned char *)payload;
103 Frame_Type_3GPP type;
104
105 int length = AMREncode(mEncoder, mSidSync, (Mode)mMode,
106 samples, bytes + 1, &type, AMR_TX_WMF);
107
108 if (type != mMode || length != (8 + gFrameBits[mMode] + 7) >> 3) {
109 return -1;
110 }
111
112 if (mOctetAligned) {
113 bytes[0] = 0xF0;
114 bytes[1] = (mMode << 3) | 0x04;
115 ++length;
116 } else {
117 // CMR = 15 (4-bit), F = 0 (1-bit), FT = mMode (4-bit), Q = 1 (1-bit).
118 bytes[0] = 0xFF;
119 bytes[1] = 0xC0 | (mMode << 1) | 1;
120
121 // Shift left 6 bits and update the length.
122 bytes[length + 1] = 0;
123 for (int i = 0; i <= length; ++i) {
124 bytes[i] = (bytes[i] << 6) | (bytes[i + 1] >> 2);
125 }
126 length = (10 + gFrameBits[mMode] + 7) >> 3;
127 }
128 return length;
129 }
130
decode(int16_t * samples,int,void * payload,int length)131 int AmrCodec::decode(int16_t *samples, int /* count */, void *payload, int length)
132 {
133 unsigned char *bytes = (unsigned char *)payload;
134 Frame_Type_3GPP type;
135 if (length < 2) {
136 return -1;
137 }
138 int request = bytes[0] >> 4;
139
140 if (mOctetAligned) {
141 if ((bytes[1] & 0xC4) != 0x04) {
142 return -1;
143 }
144 type = (Frame_Type_3GPP)(bytes[1] >> 3);
145 if (length != (16 + gFrameBits[type] + 7) >> 3) {
146 return -1;
147 }
148 length -= 2;
149 bytes += 2;
150 } else {
151 if ((bytes[0] & 0x0C) || !(bytes[1] & 0x40)) {
152 return -1;
153 }
154 type = (Frame_Type_3GPP)((bytes[0] << 1 | bytes[1] >> 7) & 0x07);
155 if (length != (10 + gFrameBits[type] + 7) >> 3) {
156 return -1;
157 }
158
159 // Shift left 2 bits and update the length.
160 --length;
161 for (int i = 1; i < length; ++i) {
162 bytes[i] = (bytes[i] << 2) | (bytes[i + 1] >> 6);
163 }
164 bytes[length] <<= 2;
165 length = (gFrameBits[type] + 7) >> 3;
166 ++bytes;
167 }
168
169 if (AMRDecode(mDecoder, type, bytes, samples, MIME_IETF) != length) {
170 return -1;
171 }
172
173 // Handle CMR
174 if (request < 8 && request != mMode) {
175 for (int i = request; i >= 0; --i) {
176 if (mModeSet & (1 << i)) {
177 mMode = request;
178 break;
179 }
180 }
181 }
182
183 return 160;
184 }
185
186 //------------------------------------------------------------------------------
187
188 // See RFC 3551 for the encoding details.
189
190 class GsmEfrCodec : public AudioCodec
191 {
192 public:
GsmEfrCodec()193 GsmEfrCodec() {
194 if (AMREncodeInit(&mEncoder, &mSidSync, false)) {
195 mEncoder = NULL;
196 }
197 if (GSMInitDecode(&mDecoder, (Word8 *)"RTP")) {
198 mDecoder = NULL;
199 }
200 }
201
~GsmEfrCodec()202 ~GsmEfrCodec() {
203 if (mEncoder) {
204 AMREncodeExit(&mEncoder, &mSidSync);
205 }
206 if (mDecoder) {
207 GSMDecodeFrameExit(&mDecoder);
208 }
209 }
210
set(int sampleRate,const char *)211 int set(int sampleRate, const char */* fmtp */) {
212 return (sampleRate == 8000 && mEncoder && mDecoder) ? 160 : -1;
213 }
214
215 int encode(void *payload, int16_t *samples);
216 int decode(int16_t *samples, int count, void *payload, int length);
217
218 private:
219 void *mEncoder;
220 void *mSidSync;
221 void *mDecoder;
222 };
223
encode(void * payload,int16_t * samples)224 int GsmEfrCodec::encode(void *payload, int16_t *samples)
225 {
226 unsigned char *bytes = (unsigned char *)payload;
227 Frame_Type_3GPP type;
228
229 int length = AMREncode(mEncoder, mSidSync, MR122,
230 samples, bytes, &type, AMR_TX_WMF);
231
232 if (type == AMR_122 && length == 32) {
233 bytes[0] = 0xC0 | (bytes[1] >> 4);
234 for (int i = 1; i < 31; ++i) {
235 bytes[i] = (bytes[i] << 4) | (bytes[i + 1] >> 4);
236 }
237 return 31;
238 }
239 return -1;
240 }
241
decode(int16_t * samples,int count,void * payload,int length)242 int GsmEfrCodec::decode(int16_t *samples, int count, void *payload, int length)
243 {
244 unsigned char *bytes = (unsigned char *)payload;
245 int n = 0;
246 while (n + 160 <= count && length >= 31 && (bytes[0] >> 4) == 0x0C) {
247 for (int i = 0; i < 30; ++i) {
248 bytes[i] = (bytes[i] << 4) | (bytes[i + 1] >> 4);
249 }
250 bytes[30] <<= 4;
251
252 if (AMRDecode(mDecoder, AMR_122, bytes, &samples[n], MIME_IETF) != 31) {
253 break;
254 }
255 n += 160;
256 length -= 31;
257 bytes += 31;
258 }
259 return n;
260 }
261
262 } // namespace
263
newAmrCodec()264 AudioCodec *newAmrCodec()
265 {
266 return new AmrCodec;
267 }
268
newGsmEfrCodec()269 AudioCodec *newGsmEfrCodec()
270 {
271 return new GsmEfrCodec;
272 }
273