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, int count, 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, int count, void *payload, int length)
     68 {
     69     int8_t *ulaws = (int8_t *)payload;
     70     if (length > count) {
     71         length = count;
     72     }
     73     for (int i = 0; i < length; ++i) {
     74         int ulaw = ~ulaws[i];
     75         int exponent = (ulaw >> 4) & 0x07;
     76         int mantissa = ulaw & 0x0F;
     77         int sample = (((mantissa << 3) + 132) << exponent) - 132;
     78         samples[i] = (ulaw < 0 ? -sample : sample);
     79     }
     80     return length;
     81 }
     82 
     83 //------------------------------------------------------------------------------
     84 
     85 class AlawCodec : public AudioCodec
     86 {
     87 public:
     88     int set(int sampleRate, const char *fmtp) {
     89         mSampleCount = sampleRate / 50;
     90         return mSampleCount;
     91     }
     92     int encode(void *payload, int16_t *samples);
     93     int decode(int16_t *samples, int count, void *payload, int length);
     94 private:
     95     int mSampleCount;
     96 };
     97 
     98 int AlawCodec::encode(void *payload, int16_t *samples)
     99 {
    100     int8_t *alaws = (int8_t *)payload;
    101     for (int i = 0; i < mSampleCount; ++i) {
    102         int sample = samples[i];
    103         int sign = (sample >> 8) & 0x80;
    104         if (sample < 0) {
    105             sample = -sample;
    106         }
    107         if (sample > 32767) {
    108             sample = 32767;
    109         }
    110         int exponent = gExponents[sample >> 8];
    111         int mantissa = (sample >> (exponent == 0 ? 4 : exponent + 3)) & 0x0F;
    112         alaws[i] = (sign | (exponent << 4) | mantissa) ^ 0xD5;
    113     }
    114     return mSampleCount;
    115 }
    116 
    117 int AlawCodec::decode(int16_t *samples, int count, void *payload, int length)
    118 {
    119     int8_t *alaws = (int8_t *)payload;
    120     if (length > count) {
    121         length = count;
    122     }
    123     for (int i = 0; i < length; ++i) {
    124         int alaw = alaws[i] ^ 0x55;
    125         int exponent = (alaw >> 4) & 0x07;
    126         int mantissa = alaw & 0x0F;
    127         int sample = (exponent == 0 ? (mantissa << 4) + 8 :
    128             ((mantissa << 3) + 132) << exponent);
    129         samples[i] = (alaw < 0 ? sample : -sample);
    130     }
    131     return length;
    132 }
    133 
    134 } // namespace
    135 
    136 AudioCodec *newUlawCodec()
    137 {
    138     return new UlawCodec;
    139 }
    140 
    141 AudioCodec *newAlawCodec()
    142 {
    143     return new AlawCodec;
    144 }
    145