1d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh/*
2d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh * Copyrightm (C) 2010 The Android Open Source Project
3d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh *
4d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh * Licensed under the Apache License, Version 2.0 (the "License");
5d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh * you may not use this file except in compliance with the License.
6d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh * You may obtain a copy of the License at
7d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh *
8d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh *      http://www.apache.org/licenses/LICENSE-2.0
9d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh *
10d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh * Unless required by applicable law or agreed to in writing, software
11d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh * distributed under the License is distributed on an "AS IS" BASIS,
12d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh * See the License for the specific language governing permissions and
14d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh * limitations under the License.
15d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh */
16d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh
17d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh#include "AudioCodec.h"
18d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh
19d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yehextern "C" {
20d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh#include "gsm.h"
21d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh}
22d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh
23d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yehnamespace {
24d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh
25d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yehclass GsmCodec : public AudioCodec
26d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh{
27d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yehpublic:
28d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh    GsmCodec() {
29d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh        mEncode = gsm_create();
30d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh        mDecode = gsm_create();
31d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh    }
32d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh
33d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh    ~GsmCodec() {
34d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh        if (mEncode) {
35d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh            gsm_destroy(mEncode);
36d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh        }
37d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh        if (mDecode) {
38d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh            gsm_destroy(mDecode);
39d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh        }
40d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh    }
41d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh
4214ef3fc99b6b2f62e93bd5bbc9a240cd59201af0Aurimas Liutikas    int set(int sampleRate, const char */* fmtp */) {
43d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh        return (sampleRate == 8000 && mEncode && mDecode) ? 160 : -1;
44d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh    }
45d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh
46d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh    int encode(void *payload, int16_t *samples);
47418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh    int decode(int16_t *samples, int count, void *payload, int length);
48d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh
49d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yehprivate:
50d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh    gsm mEncode;
51d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh    gsm mDecode;
52d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh};
53d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh
54d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yehint GsmCodec::encode(void *payload, int16_t *samples)
55d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh{
56d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh    gsm_encode(mEncode, samples, (unsigned char *)payload);
57d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh    return 33;
58d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh}
59d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh
60418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yehint GsmCodec::decode(int16_t *samples, int count, void *payload, int length)
61d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh{
62418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh    unsigned char *bytes = (unsigned char *)payload;
63418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh    int n = 0;
64418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh    while (n + 160 <= count && length >= 33 &&
65418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh        gsm_decode(mDecode, bytes, &samples[n]) == 0) {
66418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh        n += 160;
67418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh        length -= 33;
68418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh        bytes += 33;
69d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh    }
70418b5f04c2eb3ceff046328ba23a16b89a5a3306Chia-chi Yeh    return n;
71d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh}
72d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh
73d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh} // namespace
74d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh
75d0f061251d77b98b510626ddcc925a74195519dfChia-chi YehAudioCodec *newGsmCodec()
76d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh{
77d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh    return new GsmCodec;
78d0f061251d77b98b510626ddcc925a74195519dfChia-chi Yeh}
79