1536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh/* 2536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh * Copyrightm (C) 2010 The Android Open Source Project 3536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh * 4536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh * Licensed under the Apache License, Version 2.0 (the "License"); 5536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh * you may not use this file except in compliance with the License. 6536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh * You may obtain a copy of the License at 7536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh * 8536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh * http://www.apache.org/licenses/LICENSE-2.0 9536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh * 10536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh * Unless required by applicable law or agreed to in writing, software 11536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh * distributed under the License is distributed on an "AS IS" BASIS, 12536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh * See the License for the specific language governing permissions and 14536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh * limitations under the License. 15536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh */ 16536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 17536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh#include "AudioCodec.h" 18536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 19536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yehnamespace { 20536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 21d85beac45c12a65076a1c157681de9a5b03bdec7Chia-chi Yehconst int8_t gExponents[128] = { 22536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 23536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 25536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 26536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 27536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 28536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 29536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 30536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh}; 31536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 32536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh//------------------------------------------------------------------------------ 33536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 34536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yehclass UlawCodec : public AudioCodec 35536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh{ 36536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yehpublic: 37536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int set(int sampleRate, const char *fmtp) { 38536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh mSampleCount = sampleRate / 50; 39536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh return mSampleCount; 40536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh } 41536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int encode(void *payload, int16_t *samples); 42418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh int decode(int16_t *samples, int count, void *payload, int length); 43536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yehprivate: 44536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int mSampleCount; 45536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh}; 46536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 47536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yehint UlawCodec::encode(void *payload, int16_t *samples) 48536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh{ 49536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int8_t *ulaws = (int8_t *)payload; 50536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh for (int i = 0; i < mSampleCount; ++i) { 51536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int sample = samples[i]; 52536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int sign = (sample >> 8) & 0x80; 53536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh if (sample < 0) { 54536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh sample = -sample; 55536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh } 56536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh sample += 132; 57536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh if (sample > 32767) { 58536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh sample = 32767; 59536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh } 60536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int exponent = gExponents[sample >> 8]; 61536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int mantissa = (sample >> (exponent + 3)) & 0x0F; 62536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh ulaws[i] = ~(sign | (exponent << 4) | mantissa); 63536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh } 64536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh return mSampleCount; 65536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh} 66536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 67418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yehint UlawCodec::decode(int16_t *samples, int count, void *payload, int length) 68536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh{ 69536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int8_t *ulaws = (int8_t *)payload; 70418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh if (length > count) { 71418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh length = count; 72418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh } 73536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh for (int i = 0; i < length; ++i) { 74536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int ulaw = ~ulaws[i]; 75536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int exponent = (ulaw >> 4) & 0x07; 76536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int mantissa = ulaw & 0x0F; 77536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int sample = (((mantissa << 3) + 132) << exponent) - 132; 78536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh samples[i] = (ulaw < 0 ? -sample : sample); 79536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh } 80536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh return length; 81536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh} 82536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 83536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh//------------------------------------------------------------------------------ 84536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 85536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yehclass AlawCodec : public AudioCodec 86536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh{ 87536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yehpublic: 88536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int set(int sampleRate, const char *fmtp) { 89536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh mSampleCount = sampleRate / 50; 90536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh return mSampleCount; 91536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh } 92536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int encode(void *payload, int16_t *samples); 93418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh int decode(int16_t *samples, int count, void *payload, int length); 94536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yehprivate: 95536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int mSampleCount; 96536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh}; 97536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 98536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yehint AlawCodec::encode(void *payload, int16_t *samples) 99536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh{ 100536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int8_t *alaws = (int8_t *)payload; 101536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh for (int i = 0; i < mSampleCount; ++i) { 102536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int sample = samples[i]; 103536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int sign = (sample >> 8) & 0x80; 104536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh if (sample < 0) { 105536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh sample = -sample; 106536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh } 107536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh if (sample > 32767) { 108536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh sample = 32767; 109536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh } 110536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int exponent = gExponents[sample >> 8]; 111536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int mantissa = (sample >> (exponent == 0 ? 4 : exponent + 3)) & 0x0F; 112536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh alaws[i] = (sign | (exponent << 4) | mantissa) ^ 0xD5; 113536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh } 114536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh return mSampleCount; 115536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh} 116536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 117418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yehint AlawCodec::decode(int16_t *samples, int count, void *payload, int length) 118536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh{ 119536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int8_t *alaws = (int8_t *)payload; 120418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh if (length > count) { 121418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh length = count; 122418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh } 123536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh for (int i = 0; i < length; ++i) { 124536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int alaw = alaws[i] ^ 0x55; 125536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int exponent = (alaw >> 4) & 0x07; 126536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int mantissa = alaw & 0x0F; 127536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh int sample = (exponent == 0 ? (mantissa << 4) + 8 : 128536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh ((mantissa << 3) + 132) << exponent); 129536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh samples[i] = (alaw < 0 ? sample : -sample); 130536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh } 131536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh return length; 132536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh} 133536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 134536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh} // namespace 135536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 136536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi YehAudioCodec *newUlawCodec() 137536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh{ 138536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh return new UlawCodec; 139536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh} 140536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh 141536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi YehAudioCodec *newAlawCodec() 142536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh{ 143536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh return new AlawCodec; 144536a451f5cf9f4bcf38968366cf62368f3d4d2f8Chia-chi Yeh} 145