AmrCodec.cpp revision f4ae94229d736c7dbd3c5c36d484213d51545702
1f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh/* 2f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh * Copyrightm (C) 2010 The Android Open Source Project 3f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh * 4f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh * Licensed under the Apache License, Version 2.0 (the "License"); 5f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh * you may not use this file except in compliance with the License. 6f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh * You may obtain a copy of the License at 7f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh * 8f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh * http://www.apache.org/licenses/LICENSE-2.0 9f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh * 10f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh * Unless required by applicable law or agreed to in writing, software 11f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh * distributed under the License is distributed on an "AS IS" BASIS, 12f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh * See the License for the specific language governing permissions and 14f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh * limitations under the License. 15f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh */ 16f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 17f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh#include "AudioCodec.h" 18f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 19f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh#include "gsmamr_dec.h" 20f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh#include "gsmamr_enc.h" 21f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 22f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yehnamespace { 23f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 24f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yehclass GsmEfrCodec : public AudioCodec 25f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh{ 26f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yehpublic: 27f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh GsmEfrCodec() { 28f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh if (AMREncodeInit(&mEncoder, &mSidSync, false)) { 29f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh mEncoder = NULL; 30f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh } 31f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh if (GSMInitDecode(&mDecoder, (Word8 *)"RTP")) { 32f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh mDecoder = NULL; 33f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh } 34f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh } 35f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 36f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh ~GsmEfrCodec() { 37f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh if (mEncoder) { 38f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh AMREncodeExit(&mEncoder, &mSidSync); 39f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh } 40f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh if (mDecoder) { 41f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh GSMDecodeFrameExit(&mDecoder); 42f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh } 43f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh } 44f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 45f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh int set(int sampleRate, const char *fmtp) { 46f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh return (sampleRate == 8000 && mEncoder && mDecoder) ? 160 : -1; 47f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh } 48f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 49f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh int encode(void *payload, int16_t *samples); 50f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh int decode(int16_t *samples, void *payload, int length); 51f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 52f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yehprivate: 53f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh void *mEncoder; 54f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh void *mSidSync; 55f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh void *mDecoder; 56f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh}; 57f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 58f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yehint GsmEfrCodec::encode(void *payload, int16_t *samples) 59f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh{ 60f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh unsigned char *bytes = (unsigned char *)payload; 61f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh Frame_Type_3GPP type; 62f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 63f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh int length = AMREncode(mEncoder, mSidSync, MR122, 64f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh samples, bytes, &type, AMR_TX_WMF); 65f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 66f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh if (type == AMR_122 && length == 32) { 67f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh bytes[0] = 0xC0 | (bytes[1] >> 4); 68f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh for (int i = 1; i < 31; ++i) { 69f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh bytes[i] = (bytes[i] << 4) | (bytes[i + 1] >> 4); 70f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh } 71f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh return 31; 72f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh } 73f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh return -1; 74f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh} 75f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 76f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yehint GsmEfrCodec::decode(int16_t *samples, void *payload, int length) 77f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh{ 78f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh unsigned char *bytes = (unsigned char *)payload; 79f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh if (length == 31 && (bytes[0] >> 4) == 0x0C) { 80f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh for (int i = 0; i < 30; ++i) { 81f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh bytes[i] = (bytes[i] << 4) | (bytes[i + 1] >> 4); 82f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh } 83f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh bytes[30] <<= 4; 84f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 85f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh if (AMRDecode(mDecoder, AMR_122, bytes, samples, MIME_IETF) == 31) { 86f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh return 160; 87f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh } 88f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh } 89f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh return -1; 90f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh} 91f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 92f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh} // namespace 93f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh 94f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi YehAudioCodec *newGsmEfrCodec() 95f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh{ 96f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh return new GsmEfrCodec; 97f4ae94229d736c7dbd3c5c36d484213d51545702Chia-chi Yeh} 98