Home | History | Annotate | Download | only in rtp
      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 "AudioCodec.h"
     18 
     19 namespace {
     20 
     21 const int8_t gExponents[128] = {
     22     0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
     23     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
     24     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
     25     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
     26     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
     27     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
     28     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
     29     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
     30 };
     31 
     32 //------------------------------------------------------------------------------
     33 
     34 class UlawCodec : public AudioCodec
     35 {
     36 public:
     37     int set(int sampleRate, const char *fmtp) {
     38         mSampleCount = sampleRate / 50;
     39         return mSampleCount;
     40     }
     41     int encode(void *payload, int16_t *samples);
     42     int decode(int16_t *samples, void *payload, int length);
     43 private:
     44     int mSampleCount;
     45 };
     46 
     47 int UlawCodec::encode(void *payload, int16_t *samples)
     48 {
     49     int8_t *ulaws = (int8_t *)payload;
     50     for (int i = 0; i < mSampleCount; ++i) {
     51         int sample = samples[i];
     52         int sign = (sample >> 8) & 0x80;
     53         if (sample < 0) {
     54             sample = -sample;
     55         }
     56         sample += 132;
     57         if (sample > 32767) {
     58             sample = 32767;
     59         }
     60         int exponent = gExponents[sample >> 8];
     61         int mantissa = (sample >> (exponent + 3)) & 0x0F;
     62         ulaws[i] = ~(sign | (exponent << 4) | mantissa);
     63     }
     64     return mSampleCount;
     65 }
     66 
     67 int UlawCodec::decode(int16_t *samples, void *payload, int length)
     68 {
     69     int8_t *ulaws = (int8_t *)payload;
     70     for (int i = 0; i < length; ++i) {
     71         int ulaw = ~ulaws[i];
     72         int exponent = (ulaw >> 4) & 0x07;
     73         int mantissa = ulaw & 0x0F;
     74         int sample = (((mantissa << 3) + 132) << exponent) - 132;
     75         samples[i] = (ulaw < 0 ? -sample : sample);
     76     }
     77     return length;
     78 }
     79 
     80 //------------------------------------------------------------------------------
     81 
     82 class AlawCodec : public AudioCodec
     83 {
     84 public:
     85     int set(int sampleRate, const char *fmtp) {
     86         mSampleCount = sampleRate / 50;
     87         return mSampleCount;
     88     }
     89     int encode(void *payload, int16_t *samples);
     90     int decode(int16_t *samples, void *payload, int length);
     91 private:
     92     int mSampleCount;
     93 };
     94 
     95 int AlawCodec::encode(void *payload, int16_t *samples)
     96 {
     97     int8_t *alaws = (int8_t *)payload;
     98     for (int i = 0; i < mSampleCount; ++i) {
     99         int sample = samples[i];
    100         int sign = (sample >> 8) & 0x80;
    101         if (sample < 0) {
    102             sample = -sample;
    103         }
    104         if (sample > 32767) {
    105             sample = 32767;
    106         }
    107         int exponent = gExponents[sample >> 8];
    108         int mantissa = (sample >> (exponent == 0 ? 4 : exponent + 3)) & 0x0F;
    109         alaws[i] = (sign | (exponent << 4) | mantissa) ^ 0xD5;
    110     }
    111     return mSampleCount;
    112 }
    113 
    114 int AlawCodec::decode(int16_t *samples, void *payload, int length)
    115 {
    116     int8_t *alaws = (int8_t *)payload;
    117     for (int i = 0; i < length; ++i) {
    118         int alaw = alaws[i] ^ 0x55;
    119         int exponent = (alaw >> 4) & 0x07;
    120         int mantissa = alaw & 0x0F;
    121         int sample = (exponent == 0 ? (mantissa << 4) + 8 :
    122             ((mantissa << 3) + 132) << exponent);
    123         samples[i] = (alaw < 0 ? sample : -sample);
    124     }
    125     return length;
    126 }
    127 
    128 } // namespace
    129 
    130 AudioCodec *newUlawCodec()
    131 {
    132     return new UlawCodec;
    133 }
    134 
    135 AudioCodec *newAlawCodec()
    136 {
    137     return new AlawCodec;
    138 }
    139