1 /*
2 * Copyright 2023 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 "mmc/codec_server/hfp_lc3_mmc_encoder.h"
18
19 #include <bluetooth/log.h>
20 #include <lc3.h>
21
22 #include <algorithm>
23
24 #include "mmc/codec_server/lc3_utils.h"
25 #include "mmc/proto/mmc_config.pb.h"
26 #include "osi/include/allocator.h"
27
28 namespace mmc {
29
30 using namespace bluetooth;
31
HfpLc3Encoder()32 HfpLc3Encoder::HfpLc3Encoder() : hfp_lc3_encoder_mem_(nullptr) {}
33
~HfpLc3Encoder()34 HfpLc3Encoder::~HfpLc3Encoder() { cleanup(); }
35
init(ConfigParam config)36 int HfpLc3Encoder::init(ConfigParam config) {
37 cleanup();
38
39 if (!config.has_hfp_lc3_encoder_param()) {
40 log::error("HFP LC3 encoder params are not set");
41 return -EINVAL;
42 }
43
44 param_ = config.hfp_lc3_encoder_param();
45 int dt_us = param_.dt_us();
46 int sr_hz = param_.sr_hz();
47 int sr_pcm_hz = param_.sr_pcm_hz();
48 const unsigned enc_size = lc3_encoder_size(dt_us, sr_pcm_hz);
49
50 hfp_lc3_encoder_mem_ = osi_malloc(enc_size);
51
52 hfp_lc3_encoder_ =
53 lc3_setup_encoder(dt_us, sr_hz, sr_pcm_hz, hfp_lc3_encoder_mem_);
54
55 if (hfp_lc3_encoder_ == nullptr) {
56 log::error("Wrong parameters provided");
57 return -EINVAL;
58 }
59
60 return HFP_LC3_PCM_BYTES;
61 }
62
cleanup()63 void HfpLc3Encoder::cleanup() {
64 if (hfp_lc3_encoder_mem_) {
65 osi_free_and_reset((void**)&hfp_lc3_encoder_mem_);
66 log::info("Released the encoder instance");
67 }
68 }
69
transcode(uint8_t * i_buf,int i_len,uint8_t * o_buf,int o_len)70 int HfpLc3Encoder::transcode(uint8_t* i_buf, int i_len, uint8_t* o_buf,
71 int o_len) {
72 if (i_buf == nullptr || o_buf == nullptr) {
73 log::error("Buffer is null");
74 return -EINVAL;
75 }
76
77 /* Note this only fails when wrong parameters are supplied. */
78 int rc = lc3_encode(hfp_lc3_encoder_, MapLc3PcmFmt(param_.fmt()), i_buf,
79 param_.stride(), HFP_LC3_PKT_FRAME_LEN, o_buf);
80
81 if (rc != 0) {
82 log::warn("Wrong encode parameters");
83 std::fill(o_buf, o_buf + o_len, 0);
84 }
85
86 return HFP_LC3_PKT_FRAME_LEN;
87 }
88
89 } // namespace mmc
90