G711Codec.cpp revision 21ae1ad6a695d6f1f253797fcf2a77b975b82cd3
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);
4278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    int decode(int16_t *samples, 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
6778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehint UlawCodec::decode(int16_t *samples, void *payload, int length)
6878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{
6978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    int8_t *ulaws = (int8_t *)payload;
7078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    for (int i = 0; i < length; ++i) {
7178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        int ulaw = ~ulaws[i];
7278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        int exponent = (ulaw >> 4) & 0x07;
7378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        int mantissa = ulaw & 0x0F;
7478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        int sample = (((mantissa << 3) + 132) << exponent) - 132;
7578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        samples[i] = (ulaw < 0 ? -sample : sample);
7678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    }
7778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    return length;
7878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh}
7978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh
8078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh//------------------------------------------------------------------------------
8178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh
8278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehclass AlawCodec : public AudioCodec
8378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{
8478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehpublic:
8578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    int set(int sampleRate, const char *fmtp) {
8678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        mSampleCount = sampleRate / 50;
8778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        return mSampleCount;
8878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    }
8978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    int encode(void *payload, int16_t *samples);
9078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    int decode(int16_t *samples, void *payload, int length);
9178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehprivate:
9278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    int mSampleCount;
9378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh};
9478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh
9578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehint AlawCodec::encode(void *payload, int16_t *samples)
9678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{
9778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    int8_t *alaws = (int8_t *)payload;
9878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    for (int i = 0; i < mSampleCount; ++i) {
9978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        int sample = samples[i];
10078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        int sign = (sample >> 8) & 0x80;
10178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        if (sample < 0) {
10278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh            sample = -sample;
10378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        }
10478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        if (sample > 32767) {
10578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh            sample = 32767;
10678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        }
10778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        int exponent = gExponents[sample >> 8];
10878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        int mantissa = (sample >> (exponent == 0 ? 4 : exponent + 3)) & 0x0F;
10978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        alaws[i] = (sign | (exponent << 4) | mantissa) ^ 0xD5;
11078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    }
11178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    return mSampleCount;
11278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh}
11378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh
11478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yehint AlawCodec::decode(int16_t *samples, void *payload, int length)
11578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{
11678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    int8_t *alaws = (int8_t *)payload;
11778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    for (int i = 0; i < length; ++i) {
11878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        int alaw = alaws[i] ^ 0x55;
11978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        int exponent = (alaw >> 4) & 0x07;
12078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        int mantissa = alaw & 0x0F;
12178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        int sample = (exponent == 0 ? (mantissa << 4) + 8 :
12278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh            ((mantissa << 3) + 132) << exponent);
12378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh        samples[i] = (alaw < 0 ? sample : -sample);
12478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    }
12578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    return length;
12678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh}
12778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh
12878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh} // namespace
12978c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh
13078c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi YehAudioCodec *newUlawCodec()
13178c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{
13278c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    return new UlawCodec;
13378c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh}
13478c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh
13578c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi YehAudioCodec *newAlawCodec()
13678c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh{
13778c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh    return new AlawCodec;
13878c11b3cf170fdd35ff6984bc2a64c01e2457503Chia-chi Yeh}
139