1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/modules/audio_coding/main/acm2/acm_g7221c.h"
12
13#ifdef WEBRTC_CODEC_G722_1C
14// NOTE! G.722.1C is not included in the open-source package. The following
15// interface file is needed:
16#include "webrtc/modules/audio_coding/main/codecs/g7221c/interface/g7221c_interface.h"
17#include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
18#include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
19#include "webrtc/system_wrappers/interface/trace.h"
20
21// The API in the header file should match the one below.
22//
23// int16_t WebRtcG7221C_CreateEnc24(G722_1C_24_encinst_t_** enc_inst);
24// int16_t WebRtcG7221C_CreateEnc32(G722_1C_32_encinst_t_** enc_inst);
25// int16_t WebRtcG7221C_CreateEnc48(G722_1C_48_encinst_t_** enc_inst);
26// int16_t WebRtcG7221C_CreateDec24(G722_1C_24_decinst_t_** dec_inst);
27// int16_t WebRtcG7221C_CreateDec32(G722_1C_32_decinst_t_** dec_inst);
28// int16_t WebRtcG7221C_CreateDec48(G722_1C_48_decinst_t_** dec_inst);
29//
30// int16_t WebRtcG7221C_FreeEnc24(G722_1C_24_encinst_t_** enc_inst);
31// int16_t WebRtcG7221C_FreeEnc32(G722_1C_32_encinst_t_** enc_inst);
32// int16_t WebRtcG7221C_FreeEnc48(G722_1C_48_encinst_t_** enc_inst);
33// int16_t WebRtcG7221C_FreeDec24(G722_1C_24_decinst_t_** dec_inst);
34// int16_t WebRtcG7221C_FreeDec32(G722_1C_32_decinst_t_** dec_inst);
35// int16_t WebRtcG7221C_FreeDec48(G722_1C_48_decinst_t_** dec_inst);
36//
37// int16_t WebRtcG7221C_EncoderInit24(G722_1C_24_encinst_t_* enc_inst);
38// int16_t WebRtcG7221C_EncoderInit32(G722_1C_32_encinst_t_* enc_inst);
39// int16_t WebRtcG7221C_EncoderInit48(G722_1C_48_encinst_t_* enc_inst);
40// int16_t WebRtcG7221C_DecoderInit24(G722_1C_24_decinst_t_* dec_inst);
41// int16_t WebRtcG7221C_DecoderInit32(G722_1C_32_decinst_t_* dec_inst);
42// int16_t WebRtcG7221C_DecoderInit48(G722_1C_48_decinst_t_* dec_inst);
43//
44// int16_t WebRtcG7221C_Encode24(G722_1C_24_encinst_t_* enc_inst,
45//                               int16_t* input,
46//                               int16_t len,
47//                               int16_t* output);
48// int16_t WebRtcG7221C_Encode32(G722_1C_32_encinst_t_* enc_inst,
49//                               int16_t* input,
50//                               int16_t len,
51//                               int16_t* output);
52// int16_t WebRtcG7221C_Encode48(G722_1C_48_encinst_t_* enc_inst,
53//                               int16_t* input,
54//                               int16_t len,
55//                               int16_t* output);
56//
57// int16_t WebRtcG7221C_Decode24(G722_1C_24_decinst_t_* dec_inst,
58//                               int16_t* bitstream,
59//                               int16_t len,
60//                               int16_t* output);
61// int16_t WebRtcG7221C_Decode32(G722_1C_32_decinst_t_* dec_inst,
62//                               int16_t* bitstream,
63//                               int16_t len,
64//                               int16_t* output);
65// int16_t WebRtcG7221C_Decode48(G722_1C_48_decinst_t_* dec_inst,
66//                               int16_t* bitstream,
67//                               int16_t len,
68//                               int16_t* output);
69//
70// int16_t WebRtcG7221C_DecodePlc24(G722_1C_24_decinst_t_* dec_inst,
71//                                  int16_t* output,
72//                                  int16_t nr_lost_frames);
73// int16_t WebRtcG7221C_DecodePlc32(G722_1C_32_decinst_t_* dec_inst,
74//                                  int16_t* output,
75//                                  int16_t nr_lost_frames);
76// int16_t WebRtcG7221C_DecodePlc48(G722_1C_48_decinst_t_* dec_inst,
77//                                  int16_t* output,
78//                                  int16_t nr_lost_frames);
79#endif
80
81namespace webrtc {
82
83namespace acm2 {
84
85#ifndef WEBRTC_CODEC_G722_1C
86
87ACMG722_1C::ACMG722_1C(int16_t /* codec_id */)
88    : operational_rate_(-1),
89      encoder_inst_ptr_(NULL),
90      encoder_inst_ptr_right_(NULL),
91      encoder_inst24_ptr_(NULL),
92      encoder_inst24_ptr_right_(NULL),
93      encoder_inst32_ptr_(NULL),
94      encoder_inst32_ptr_right_(NULL),
95      encoder_inst48_ptr_(NULL),
96      encoder_inst48_ptr_right_(NULL) {
97  return;
98}
99
100ACMG722_1C::~ACMG722_1C() { return; }
101
102int16_t ACMG722_1C::InternalEncode(uint8_t* /* bitstream */,
103                                   int16_t* /* bitstream_len_byte */) {
104  return -1;
105}
106
107int16_t ACMG722_1C::InternalInitEncoder(
108    WebRtcACMCodecParams* /* codec_params */) {
109  return -1;
110}
111
112ACMGenericCodec* ACMG722_1C::CreateInstance(void) { return NULL; }
113
114int16_t ACMG722_1C::InternalCreateEncoder() { return -1; }
115
116void ACMG722_1C::DestructEncoderSafe() { return; }
117
118#else  //===================== Actual Implementation =======================
119ACMG722_1C::ACMG722_1C(int16_t codec_id)
120    : encoder_inst_ptr_(NULL),
121      encoder_inst_ptr_right_(NULL),
122      encoder_inst24_ptr_(NULL),
123      encoder_inst24_ptr_right_(NULL),
124      encoder_inst32_ptr_(NULL),
125      encoder_inst32_ptr_right_(NULL),
126      encoder_inst48_ptr_(NULL),
127      encoder_inst48_ptr_right_(NULL) {
128  codec_id_ = codec_id;
129  if (codec_id_ == ACMCodecDB::kG722_1C_24) {
130    operational_rate_ = 24000;
131  } else if (codec_id_ == ACMCodecDB::kG722_1C_32) {
132    operational_rate_ = 32000;
133  } else if (codec_id_ == ACMCodecDB::kG722_1C_48) {
134    operational_rate_ = 48000;
135  } else {
136    WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
137                 "Wrong codec id for G722_1c.");
138    operational_rate_ = -1;
139  }
140  return;
141}
142
143ACMG722_1C::~ACMG722_1C() {
144  if (encoder_inst_ptr_ != NULL) {
145    delete encoder_inst_ptr_;
146    encoder_inst_ptr_ = NULL;
147  }
148  if (encoder_inst_ptr_right_ != NULL) {
149    delete encoder_inst_ptr_right_;
150    encoder_inst_ptr_right_ = NULL;
151  }
152
153  switch (operational_rate_) {
154    case 24000: {
155      encoder_inst24_ptr_ = NULL;
156      encoder_inst24_ptr_right_ = NULL;
157      break;
158    }
159    case 32000: {
160      encoder_inst32_ptr_ = NULL;
161      encoder_inst32_ptr_right_ = NULL;
162      break;
163    }
164    case 48000: {
165      encoder_inst48_ptr_ = NULL;
166      encoder_inst48_ptr_right_ = NULL;
167      break;
168    }
169    default: {
170      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
171                   "Wrong rate for G722_1c.");
172      break;
173    }
174  }
175  return;
176}
177
178int16_t ACMG722_1C::InternalEncode(uint8_t* bitstream,
179                                   int16_t* bitstream_len_byte) {
180  int16_t left_channel[640];
181  int16_t right_channel[640];
182  int16_t len_in_bytes;
183  int16_t out_bits[240];
184
185  // If stereo, split input signal in left and right channel before encoding
186  if (num_channels_ == 2) {
187    for (int i = 0, j = 0; i < frame_len_smpl_ * 2; i += 2, j++) {
188      left_channel[j] = in_audio_[in_audio_ix_read_ + i];
189      right_channel[j] = in_audio_[in_audio_ix_read_ + i + 1];
190    }
191  } else {
192    memcpy(left_channel, &in_audio_[in_audio_ix_read_], 640);
193  }
194
195  switch (operational_rate_) {
196    case 24000: {
197      len_in_bytes = WebRtcG7221C_Encode24(encoder_inst24_ptr_, left_channel,
198                                           640, &out_bits[0]);
199      if (num_channels_ == 2) {
200        len_in_bytes += WebRtcG7221C_Encode24(encoder_inst24_ptr_right_,
201                                              right_channel, 640,
202                                              &out_bits[len_in_bytes / 2]);
203      }
204      break;
205    }
206    case 32000: {
207      len_in_bytes = WebRtcG7221C_Encode32(encoder_inst32_ptr_, left_channel,
208                                           640, &out_bits[0]);
209      if (num_channels_ == 2) {
210        len_in_bytes += WebRtcG7221C_Encode32(encoder_inst32_ptr_right_,
211                                              right_channel, 640,
212                                              &out_bits[len_in_bytes / 2]);
213      }
214      break;
215    }
216    case 48000: {
217      len_in_bytes = WebRtcG7221C_Encode48(encoder_inst48_ptr_, left_channel,
218                                           640, &out_bits[0]);
219      if (num_channels_ == 2) {
220        len_in_bytes += WebRtcG7221C_Encode48(encoder_inst48_ptr_right_,
221                                              right_channel, 640,
222                                              &out_bits[len_in_bytes / 2]);
223      }
224      break;
225    }
226    default: {
227      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
228                   "InternalEncode: Wrong rate for G722_1c.");
229      return -1;
230    }
231  }
232
233  memcpy(bitstream, out_bits, len_in_bytes);
234  *bitstream_len_byte = len_in_bytes;
235
236  // increment the read index this tell the caller that how far
237  // we have gone forward in reading the audio buffer
238  in_audio_ix_read_ += 640 * num_channels_;
239
240  return *bitstream_len_byte;
241}
242
243int16_t ACMG722_1C::InternalInitEncoder(WebRtcACMCodecParams* codec_params) {
244  int16_t ret;
245
246  switch (operational_rate_) {
247    case 24000: {
248      ret = WebRtcG7221C_EncoderInit24(encoder_inst24_ptr_right_);
249      if (ret < 0) {
250        return ret;
251      }
252      return WebRtcG7221C_EncoderInit24(encoder_inst24_ptr_);
253    }
254    case 32000: {
255      ret = WebRtcG7221C_EncoderInit32(encoder_inst32_ptr_right_);
256      if (ret < 0) {
257        return ret;
258      }
259      return WebRtcG7221C_EncoderInit32(encoder_inst32_ptr_);
260    }
261    case 48000: {
262      ret = WebRtcG7221C_EncoderInit48(encoder_inst48_ptr_right_);
263      if (ret < 0) {
264        return ret;
265      }
266      return WebRtcG7221C_EncoderInit48(encoder_inst48_ptr_);
267    }
268    default: {
269      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
270                   "InternalInitEncode: Wrong rate for G722_1c.");
271      return -1;
272    }
273  }
274}
275
276ACMGenericCodec* ACMG722_1C::CreateInstance(void) { return NULL; }
277
278int16_t ACMG722_1C::InternalCreateEncoder() {
279  if ((encoder_inst_ptr_ == NULL) || (encoder_inst_ptr_right_ == NULL)) {
280    return -1;
281  }
282  switch (operational_rate_) {
283    case 24000: {
284      WebRtcG7221C_CreateEnc24(&encoder_inst24_ptr_);
285      WebRtcG7221C_CreateEnc24(&encoder_inst24_ptr_right_);
286      break;
287    }
288    case 32000: {
289      WebRtcG7221C_CreateEnc32(&encoder_inst32_ptr_);
290      WebRtcG7221C_CreateEnc32(&encoder_inst32_ptr_right_);
291      break;
292    }
293    case 48000: {
294      WebRtcG7221C_CreateEnc48(&encoder_inst48_ptr_);
295      WebRtcG7221C_CreateEnc48(&encoder_inst48_ptr_right_);
296      break;
297    }
298    default: {
299      WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
300                   "InternalCreateEncoder: Wrong rate for G722_1c.");
301      return -1;
302    }
303  }
304  return 0;
305}
306
307void ACMG722_1C::DestructEncoderSafe() {
308  encoder_exist_ = false;
309  encoder_initialized_ = false;
310  if (encoder_inst_ptr_ != NULL) {
311    delete encoder_inst_ptr_;
312    encoder_inst_ptr_ = NULL;
313  }
314  if (encoder_inst_ptr_right_ != NULL) {
315    delete encoder_inst_ptr_right_;
316    encoder_inst_ptr_right_ = NULL;
317  }
318  encoder_inst24_ptr_ = NULL;
319  encoder_inst32_ptr_ = NULL;
320  encoder_inst48_ptr_ = NULL;
321}
322
323#endif
324
325}  // namespace acm2
326
327}  // namespace webrtc
328