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: 35 AmrCodec() { 36 if (AMREncodeInit(&mEncoder, &mSidSync, false)) { 37 mEncoder = NULL; 38 } 39 if (GSMInitDecode(&mDecoder, (Word8 *)"RTP")) { 40 mDecoder = NULL; 41 } 42 } 43 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 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 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 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: 193 GsmEfrCodec() { 194 if (AMREncodeInit(&mEncoder, &mSidSync, false)) { 195 mEncoder = NULL; 196 } 197 if (GSMInitDecode(&mDecoder, (Word8 *)"RTP")) { 198 mDecoder = NULL; 199 } 200 } 201 202 ~GsmEfrCodec() { 203 if (mEncoder) { 204 AMREncodeExit(&mEncoder, &mSidSync); 205 } 206 if (mDecoder) { 207 GSMDecodeFrameExit(&mDecoder); 208 } 209 } 210 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 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 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 264 AudioCodec *newAmrCodec() 265 { 266 return new AmrCodec; 267 } 268 269 AudioCodec *newGsmEfrCodec() 270 { 271 return new GsmEfrCodec; 272 } 273