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 extern "C" {
20 #include "gsm.h"
21 }
22 
23 namespace {
24 
25 class GsmCodec : public AudioCodec
26 {
27 public:
GsmCodec()28     GsmCodec() {
29         mEncode = gsm_create();
30         mDecode = gsm_create();
31     }
32 
~GsmCodec()33     ~GsmCodec() {
34         if (mEncode) {
35             gsm_destroy(mEncode);
36         }
37         if (mDecode) {
38             gsm_destroy(mDecode);
39         }
40     }
41 
set(int sampleRate,const char * fmtp)42     int set(int sampleRate, const char *fmtp) {
43         return (sampleRate == 8000 && mEncode && mDecode) ? 160 : -1;
44     }
45 
46     int encode(void *payload, int16_t *samples);
47     int decode(int16_t *samples, int count, void *payload, int length);
48 
49 private:
50     gsm mEncode;
51     gsm mDecode;
52 };
53 
encode(void * payload,int16_t * samples)54 int GsmCodec::encode(void *payload, int16_t *samples)
55 {
56     gsm_encode(mEncode, samples, (unsigned char *)payload);
57     return 33;
58 }
59 
decode(int16_t * samples,int count,void * payload,int length)60 int GsmCodec::decode(int16_t *samples, int count, void *payload, int length)
61 {
62     unsigned char *bytes = (unsigned char *)payload;
63     int n = 0;
64     while (n + 160 <= count && length >= 33 &&
65         gsm_decode(mDecode, bytes, &samples[n]) == 0) {
66         n += 160;
67         length -= 33;
68         bytes += 33;
69     }
70     return n;
71 }
72 
73 } // namespace
74 
newGsmCodec()75 AudioCodec *newGsmCodec()
76 {
77     return new GsmCodec;
78 }
79