178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh/* 278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh * Copyrightm (C) 2010 The Android Open Source Project 378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh * 478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh * Licensed under the Apache License, Version 2.0 (the "License"); 578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh * you may not use this file except in compliance with the License. 678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh * You may obtain a copy of the License at 778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh * 878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh * http://www.apache.org/licenses/LICENSE-2.0 978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh * 1078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh * Unless required by applicable law or agreed to in writing, software 1178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh * distributed under the License is distributed on an "AS IS" BASIS, 1278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh * See the License for the specific language governing permissions and 1478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh * limitations under the License. 1578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh */ 1678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 1778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh#include "AudioCodec.h" 1878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 1978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehnamespace { 2078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 2121ae1ad6a695d6f1f253797fcf2a77b975b82cd3Chia-chi Yehconst int8_t gExponents[128] = { 2278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 2378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 2978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh}; 3178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 3278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh//------------------------------------------------------------------------------ 3378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 3478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehclass UlawCodec : public AudioCodec 3578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{ 3678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehpublic: 3778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int set(int sampleRate, const char *fmtp) { 3878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh mSampleCount = sampleRate / 50; 3978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh return mSampleCount; 4078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh } 4178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int encode(void *payload, int16_t *samples); 4235d05dcba1e829782813b6ec21afceb5cffc22e6Chia-chi Yeh int decode(int16_t *samples, int count, void *payload, int length); 4378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehprivate: 4478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int mSampleCount; 4578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh}; 4678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 4778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehint UlawCodec::encode(void *payload, int16_t *samples) 4878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{ 4978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int8_t *ulaws = (int8_t *)payload; 5078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh for (int i = 0; i < mSampleCount; ++i) { 5178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int sample = samples[i]; 5278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int sign = (sample >> 8) & 0x80; 5378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh if (sample < 0) { 5478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh sample = -sample; 5578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh } 5678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh sample += 132; 5778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh if (sample > 32767) { 5878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh sample = 32767; 5978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh } 6078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int exponent = gExponents[sample >> 8]; 6178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int mantissa = (sample >> (exponent + 3)) & 0x0F; 6278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh ulaws[i] = ~(sign | (exponent << 4) | mantissa); 6378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh } 6478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh return mSampleCount; 6578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh} 6678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 6735d05dcba1e829782813b6ec21afceb5cffc22e6Chia-chi Yehint UlawCodec::decode(int16_t *samples, int count, void *payload, int length) 6878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{ 6978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int8_t *ulaws = (int8_t *)payload; 7035d05dcba1e829782813b6ec21afceb5cffc22e6Chia-chi Yeh if (length > count) { 7135d05dcba1e829782813b6ec21afceb5cffc22e6Chia-chi Yeh length = count; 7235d05dcba1e829782813b6ec21afceb5cffc22e6Chia-chi Yeh } 7378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh for (int i = 0; i < length; ++i) { 7478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int ulaw = ~ulaws[i]; 7578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int exponent = (ulaw >> 4) & 0x07; 7678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int mantissa = ulaw & 0x0F; 7778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int sample = (((mantissa << 3) + 132) << exponent) - 132; 7878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh samples[i] = (ulaw < 0 ? -sample : sample); 7978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh } 8078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh return length; 8178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh} 8278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 8378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh//------------------------------------------------------------------------------ 8478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 8578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehclass AlawCodec : public AudioCodec 8678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{ 8778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehpublic: 8878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int set(int sampleRate, const char *fmtp) { 8978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh mSampleCount = sampleRate / 50; 9078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh return mSampleCount; 9178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh } 9278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int encode(void *payload, int16_t *samples); 9335d05dcba1e829782813b6ec21afceb5cffc22e6Chia-chi Yeh int decode(int16_t *samples, int count, void *payload, int length); 9478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehprivate: 9578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int mSampleCount; 9678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh}; 9778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 9878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehint AlawCodec::encode(void *payload, int16_t *samples) 9978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{ 10078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int8_t *alaws = (int8_t *)payload; 10178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh for (int i = 0; i < mSampleCount; ++i) { 10278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int sample = samples[i]; 10378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int sign = (sample >> 8) & 0x80; 10478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh if (sample < 0) { 10578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh sample = -sample; 10678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh } 10778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh if (sample > 32767) { 10878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh sample = 32767; 10978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh } 11078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int exponent = gExponents[sample >> 8]; 11178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int mantissa = (sample >> (exponent == 0 ? 4 : exponent + 3)) & 0x0F; 11278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh alaws[i] = (sign | (exponent << 4) | mantissa) ^ 0xD5; 11378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh } 11478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh return mSampleCount; 11578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh} 11678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 11735d05dcba1e829782813b6ec21afceb5cffc22e6Chia-chi Yehint AlawCodec::decode(int16_t *samples, int count, void *payload, int length) 11878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{ 11978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int8_t *alaws = (int8_t *)payload; 12035d05dcba1e829782813b6ec21afceb5cffc22e6Chia-chi Yeh if (length > count) { 12135d05dcba1e829782813b6ec21afceb5cffc22e6Chia-chi Yeh length = count; 12235d05dcba1e829782813b6ec21afceb5cffc22e6Chia-chi Yeh } 12378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh for (int i = 0; i < length; ++i) { 12478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int alaw = alaws[i] ^ 0x55; 12578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int exponent = (alaw >> 4) & 0x07; 12678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int mantissa = alaw & 0x0F; 12778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh int sample = (exponent == 0 ? (mantissa << 4) + 8 : 12878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh ((mantissa << 3) + 132) << exponent); 12978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh samples[i] = (alaw < 0 ? sample : -sample); 13078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh } 13178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh return length; 13278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh} 13378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 13478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh} // namespace 13578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 13678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi YehAudioCodec *newUlawCodec() 13778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{ 13878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh return new UlawCodec; 13978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh} 14078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh 14178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi YehAudioCodec *newAlawCodec() 14278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{ 14378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh return new AlawCodec; 14478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh} 145