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_ = lc3_setup_encoder(dt_us, sr_hz, sr_pcm_hz, hfp_lc3_encoder_mem_);
53
54 if (hfp_lc3_encoder_ == nullptr) {
55 log::error("Wrong parameters provided");
56 return -EINVAL;
57 }
58
59 return HFP_LC3_PCM_BYTES;
60 }
61
cleanup()62 void HfpLc3Encoder::cleanup() {
63 if (hfp_lc3_encoder_mem_) {
64 osi_free_and_reset((void**)&hfp_lc3_encoder_mem_);
65 log::info("Released the encoder instance");
66 }
67 }
68
transcode(uint8_t * i_buf,int i_len,uint8_t * o_buf,int o_len)69 int HfpLc3Encoder::transcode(uint8_t* i_buf, int i_len, uint8_t* o_buf, int o_len) {
70 if (i_buf == nullptr || o_buf == nullptr) {
71 log::error("Buffer is null");
72 return -EINVAL;
73 }
74
75 /* Note this only fails when wrong parameters are supplied. */
76 int rc = lc3_encode(hfp_lc3_encoder_, MapLc3PcmFmt(param_.fmt()), i_buf, param_.stride(),
77 HFP_LC3_PKT_FRAME_LEN, o_buf);
78
79 if (rc != 0) {
80 log::warn("Wrong encode parameters");
81 std::fill(o_buf, o_buf + o_len, 0);
82 }
83
84 return HFP_LC3_PKT_FRAME_LEN;
85 }
86
87 } // namespace mmc
88