Loading system/stack/mmc/codec_server/BUILD.gn 0 → 100644 +34 −0 Original line number Diff line number Diff line # # Copyright 2023 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # source_set("libcodec_server_hfp_lc3"){ configs += [ "//bt/system/stack/mmc:target_defaults" ] include_dirs = [ "//bt/system", "//bt/system/include", "//bt/system/stack", "//bt/system/stack/include", ] deps = [ "//bt/system/stack/mmc/proto:mmc_config_proto", "//bt/system/embdrv/lc3:liblc3", "//bt/system/osi", ] sources = [ "hfp_lc3_mmc_encoder.cc", "hfp_lc3_mmc_decoder.cc", ] } system/stack/mmc/codec_server/hfp_lc3_mmc_decoder.cc 0 → 100644 +93 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mmc/codec_server/hfp_lc3_mmc_decoder.h" #include <base/logging.h> #include <errno.h> #include "embdrv/lc3/include/lc3.h" #include "mmc/codec_server/lc3_utils.h" #include "mmc/proto/mmc_config.pb.h" #include "osi/include/allocator.h" namespace mmc { HfpLc3Decoder::HfpLc3Decoder() : hfp_lc3_decoder_mem_(nullptr) {} HfpLc3Decoder::~HfpLc3Decoder() { cleanup(); } int HfpLc3Decoder::init(ConfigParam config) { cleanup(); if (!config.has_hfp_lc3_decoder_param()) { LOG(ERROR) << "HFP LC3 decoder params are not set"; return -EINVAL; } param_ = config.hfp_lc3_decoder_param(); int dt_us = param_.dt_us(); int sr_hz = param_.sr_hz(); int sr_pcm_hz = param_.sr_pcm_hz(); const unsigned dec_size = lc3_decoder_size(dt_us, sr_pcm_hz); hfp_lc3_decoder_mem_ = osi_malloc(dec_size); hfp_lc3_decoder_ = lc3_setup_decoder(dt_us, sr_hz, sr_pcm_hz, hfp_lc3_decoder_mem_); if (hfp_lc3_decoder_ == nullptr) { LOG(ERROR) << "Wrong parameters provided"; return -EINVAL; } return HFP_LC3_PKT_FRAME_LEN; } void HfpLc3Decoder::cleanup() { if (hfp_lc3_decoder_mem_) { osi_free_and_reset((void**)&hfp_lc3_decoder_mem_); LOG(INFO) << "Released the decoder instance"; } } int HfpLc3Decoder::transcode(uint8_t* i_buf, int i_len, uint8_t* o_buf, int o_len) { if (o_buf == nullptr || o_len < HFP_LC3_PCM_BYTES + 1) { LOG(ERROR) << "Output buffer size is less than LC3 frame size"; return -EINVAL; } // Check header to decide whether it's PLC. uint8_t* in_frame = (i_buf[0] || i_buf[1]) ? i_buf + HFP_LC3_H2_HEADER_LEN : nullptr; // First byte is reserved to indicate PLC. uint8_t* out_frame = o_buf + 1; /* Note this only fails when wrong parameters are supplied. */ int rc = lc3_decode(hfp_lc3_decoder_, in_frame, HFP_LC3_PKT_FRAME_LEN, MapLc3PcmFmt(param_.fmt()), out_frame, param_.stride()); if (rc != 0 && rc != 1) { LOG(WARNING) << "Wrong decode parameters"; std::fill(o_buf, o_buf + o_len, 0); } else o_buf[0] = rc; return HFP_LC3_PCM_BYTES + 1; } } // namespace mmc system/stack/mmc/codec_server/hfp_lc3_mmc_decoder.h 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MMC_CODEC_SERVER_HFP_LC3_MMC_DECODER_H_ #define MMC_CODEC_SERVER_HFP_LC3_MMC_DECODER_H_ #include "embdrv/lc3/include/lc3.h" #include "mmc/mmc_interface/mmc_interface.h" #include "mmc/proto/mmc_config.pb.h" namespace mmc { // Implementation of MmcInterface. // HfpLc3Decoder wraps lc3 decode libraries. class HfpLc3Decoder : public MmcInterface { public: explicit HfpLc3Decoder(); ~HfpLc3Decoder(); // HfpLc3Decoder is neither copyable nor movable. HfpLc3Decoder(const HfpLc3Decoder&) = delete; HfpLc3Decoder& operator=(const HfpLc3Decoder&) = delete; // Inits decoder instance. // // Returns: // Input packet size accepted by the decoder, if init succeeded. // Negative errno on error, otherwise. int init(ConfigParam config) override; // Releases decoder instance. void cleanup() override; // Decodes data from |i_buf| and stores the result in |o_buf|. // // Returns: // Decoded data length, if decode succeeded. // Negative errno on error, otherwise. int transcode(uint8_t* i_buf, int i_len, uint8_t* o_buf, int o_len) override; private: void* hfp_lc3_decoder_mem_; lc3_decoder_t hfp_lc3_decoder_; Lc3Param param_; }; } // namespace mmc #endif // MMC_CODEC_SERVER_HFP_LC3_MMC_DECODER_H_ system/stack/mmc/codec_server/hfp_lc3_mmc_encoder.cc 0 → 100644 +88 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mmc/codec_server/hfp_lc3_mmc_encoder.h" #include <base/logging.h> #include <errno.h> #include <algorithm> #include "embdrv/lc3/include/lc3.h" #include "mmc/codec_server/lc3_utils.h" #include "mmc/proto/mmc_config.pb.h" #include "osi/include/allocator.h" namespace mmc { HfpLc3Encoder::HfpLc3Encoder() : hfp_lc3_encoder_mem_(nullptr) {} HfpLc3Encoder::~HfpLc3Encoder() { cleanup(); } int HfpLc3Encoder::init(ConfigParam config) { cleanup(); if (!config.has_hfp_lc3_encoder_param()) { LOG(ERROR) << "HFP LC3 encoder params are not set"; return -EINVAL; } param_ = config.hfp_lc3_encoder_param(); int dt_us = param_.dt_us(); int sr_hz = param_.sr_hz(); int sr_pcm_hz = param_.sr_pcm_hz(); const unsigned enc_size = lc3_encoder_size(dt_us, sr_pcm_hz); hfp_lc3_encoder_mem_ = osi_malloc(enc_size); hfp_lc3_encoder_ = lc3_setup_encoder(dt_us, sr_hz, sr_pcm_hz, hfp_lc3_encoder_mem_); if (hfp_lc3_encoder_ == nullptr) { LOG(ERROR) << "Wrong parameters provided"; return -EINVAL; } return HFP_LC3_PCM_BYTES; } void HfpLc3Encoder::cleanup() { if (hfp_lc3_encoder_mem_) { osi_free_and_reset((void**)&hfp_lc3_encoder_mem_); LOG(INFO) << "Released the encoder instance"; } } int HfpLc3Encoder::transcode(uint8_t* i_buf, int i_len, uint8_t* o_buf, int o_len) { if (i_buf == nullptr || o_buf == nullptr) { LOG(ERROR) << "Buffer is null"; return -EINVAL; } /* Note this only fails when wrong parameters are supplied. */ int rc = lc3_encode(hfp_lc3_encoder_, MapLc3PcmFmt(param_.fmt()), i_buf, param_.stride(), HFP_LC3_PKT_FRAME_LEN, o_buf); if (rc != 0) { LOG(WARNING) << "Wrong encode parameters"; std::fill(o_buf, o_buf + o_len, 0); } return HFP_LC3_PKT_FRAME_LEN; } } // namespace mmc system/stack/mmc/codec_server/hfp_lc3_mmc_encoder.h 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MMC_CODEC_SERVER_HFP_LC3_MMC_ENCODER_H_ #define MMC_CODEC_SERVER_HFP_LC3_MMC_ENCODER_H_ #include "embdrv/lc3/include/lc3.h" #include "mmc/mmc_interface/mmc_interface.h" #include "mmc/proto/mmc_config.pb.h" namespace mmc { // Implementation of MmcInterface. // HfpLc3Encoder wraps lc3 encode libraries. class HfpLc3Encoder : public MmcInterface { public: explicit HfpLc3Encoder(); ~HfpLc3Encoder(); // HfpLc3Encoder is neither copyable nor movable. HfpLc3Encoder(const HfpLc3Encoder&) = delete; HfpLc3Encoder& operator=(const HfpLc3Encoder&) = delete; // Inits encoder instance. // // Returns: // Input pcm frame size accepted by the encoder, if init succeeded. // Negative errno on error, otherwise. int init(ConfigParam config) override; // Releases encoder instance. void cleanup() override; // Encodes data from |i_buf|, and stores the result to |o_buf|. // // Returns: // Encoded data length, if encode succeeded. // Negative errno on error, otherwise. int transcode(uint8_t* i_buf, int i_len, uint8_t* o_buf, int o_len) override; private: void* hfp_lc3_encoder_mem_; lc3_encoder_t hfp_lc3_encoder_; Lc3Param param_; }; } // namespace mmc #endif // MMC_CODEC_SERVER_HFP_LC3_MMC_ENCODER_H_ Loading
system/stack/mmc/codec_server/BUILD.gn 0 → 100644 +34 −0 Original line number Diff line number Diff line # # Copyright 2023 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # source_set("libcodec_server_hfp_lc3"){ configs += [ "//bt/system/stack/mmc:target_defaults" ] include_dirs = [ "//bt/system", "//bt/system/include", "//bt/system/stack", "//bt/system/stack/include", ] deps = [ "//bt/system/stack/mmc/proto:mmc_config_proto", "//bt/system/embdrv/lc3:liblc3", "//bt/system/osi", ] sources = [ "hfp_lc3_mmc_encoder.cc", "hfp_lc3_mmc_decoder.cc", ] }
system/stack/mmc/codec_server/hfp_lc3_mmc_decoder.cc 0 → 100644 +93 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mmc/codec_server/hfp_lc3_mmc_decoder.h" #include <base/logging.h> #include <errno.h> #include "embdrv/lc3/include/lc3.h" #include "mmc/codec_server/lc3_utils.h" #include "mmc/proto/mmc_config.pb.h" #include "osi/include/allocator.h" namespace mmc { HfpLc3Decoder::HfpLc3Decoder() : hfp_lc3_decoder_mem_(nullptr) {} HfpLc3Decoder::~HfpLc3Decoder() { cleanup(); } int HfpLc3Decoder::init(ConfigParam config) { cleanup(); if (!config.has_hfp_lc3_decoder_param()) { LOG(ERROR) << "HFP LC3 decoder params are not set"; return -EINVAL; } param_ = config.hfp_lc3_decoder_param(); int dt_us = param_.dt_us(); int sr_hz = param_.sr_hz(); int sr_pcm_hz = param_.sr_pcm_hz(); const unsigned dec_size = lc3_decoder_size(dt_us, sr_pcm_hz); hfp_lc3_decoder_mem_ = osi_malloc(dec_size); hfp_lc3_decoder_ = lc3_setup_decoder(dt_us, sr_hz, sr_pcm_hz, hfp_lc3_decoder_mem_); if (hfp_lc3_decoder_ == nullptr) { LOG(ERROR) << "Wrong parameters provided"; return -EINVAL; } return HFP_LC3_PKT_FRAME_LEN; } void HfpLc3Decoder::cleanup() { if (hfp_lc3_decoder_mem_) { osi_free_and_reset((void**)&hfp_lc3_decoder_mem_); LOG(INFO) << "Released the decoder instance"; } } int HfpLc3Decoder::transcode(uint8_t* i_buf, int i_len, uint8_t* o_buf, int o_len) { if (o_buf == nullptr || o_len < HFP_LC3_PCM_BYTES + 1) { LOG(ERROR) << "Output buffer size is less than LC3 frame size"; return -EINVAL; } // Check header to decide whether it's PLC. uint8_t* in_frame = (i_buf[0] || i_buf[1]) ? i_buf + HFP_LC3_H2_HEADER_LEN : nullptr; // First byte is reserved to indicate PLC. uint8_t* out_frame = o_buf + 1; /* Note this only fails when wrong parameters are supplied. */ int rc = lc3_decode(hfp_lc3_decoder_, in_frame, HFP_LC3_PKT_FRAME_LEN, MapLc3PcmFmt(param_.fmt()), out_frame, param_.stride()); if (rc != 0 && rc != 1) { LOG(WARNING) << "Wrong decode parameters"; std::fill(o_buf, o_buf + o_len, 0); } else o_buf[0] = rc; return HFP_LC3_PCM_BYTES + 1; } } // namespace mmc
system/stack/mmc/codec_server/hfp_lc3_mmc_decoder.h 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MMC_CODEC_SERVER_HFP_LC3_MMC_DECODER_H_ #define MMC_CODEC_SERVER_HFP_LC3_MMC_DECODER_H_ #include "embdrv/lc3/include/lc3.h" #include "mmc/mmc_interface/mmc_interface.h" #include "mmc/proto/mmc_config.pb.h" namespace mmc { // Implementation of MmcInterface. // HfpLc3Decoder wraps lc3 decode libraries. class HfpLc3Decoder : public MmcInterface { public: explicit HfpLc3Decoder(); ~HfpLc3Decoder(); // HfpLc3Decoder is neither copyable nor movable. HfpLc3Decoder(const HfpLc3Decoder&) = delete; HfpLc3Decoder& operator=(const HfpLc3Decoder&) = delete; // Inits decoder instance. // // Returns: // Input packet size accepted by the decoder, if init succeeded. // Negative errno on error, otherwise. int init(ConfigParam config) override; // Releases decoder instance. void cleanup() override; // Decodes data from |i_buf| and stores the result in |o_buf|. // // Returns: // Decoded data length, if decode succeeded. // Negative errno on error, otherwise. int transcode(uint8_t* i_buf, int i_len, uint8_t* o_buf, int o_len) override; private: void* hfp_lc3_decoder_mem_; lc3_decoder_t hfp_lc3_decoder_; Lc3Param param_; }; } // namespace mmc #endif // MMC_CODEC_SERVER_HFP_LC3_MMC_DECODER_H_
system/stack/mmc/codec_server/hfp_lc3_mmc_encoder.cc 0 → 100644 +88 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mmc/codec_server/hfp_lc3_mmc_encoder.h" #include <base/logging.h> #include <errno.h> #include <algorithm> #include "embdrv/lc3/include/lc3.h" #include "mmc/codec_server/lc3_utils.h" #include "mmc/proto/mmc_config.pb.h" #include "osi/include/allocator.h" namespace mmc { HfpLc3Encoder::HfpLc3Encoder() : hfp_lc3_encoder_mem_(nullptr) {} HfpLc3Encoder::~HfpLc3Encoder() { cleanup(); } int HfpLc3Encoder::init(ConfigParam config) { cleanup(); if (!config.has_hfp_lc3_encoder_param()) { LOG(ERROR) << "HFP LC3 encoder params are not set"; return -EINVAL; } param_ = config.hfp_lc3_encoder_param(); int dt_us = param_.dt_us(); int sr_hz = param_.sr_hz(); int sr_pcm_hz = param_.sr_pcm_hz(); const unsigned enc_size = lc3_encoder_size(dt_us, sr_pcm_hz); hfp_lc3_encoder_mem_ = osi_malloc(enc_size); hfp_lc3_encoder_ = lc3_setup_encoder(dt_us, sr_hz, sr_pcm_hz, hfp_lc3_encoder_mem_); if (hfp_lc3_encoder_ == nullptr) { LOG(ERROR) << "Wrong parameters provided"; return -EINVAL; } return HFP_LC3_PCM_BYTES; } void HfpLc3Encoder::cleanup() { if (hfp_lc3_encoder_mem_) { osi_free_and_reset((void**)&hfp_lc3_encoder_mem_); LOG(INFO) << "Released the encoder instance"; } } int HfpLc3Encoder::transcode(uint8_t* i_buf, int i_len, uint8_t* o_buf, int o_len) { if (i_buf == nullptr || o_buf == nullptr) { LOG(ERROR) << "Buffer is null"; return -EINVAL; } /* Note this only fails when wrong parameters are supplied. */ int rc = lc3_encode(hfp_lc3_encoder_, MapLc3PcmFmt(param_.fmt()), i_buf, param_.stride(), HFP_LC3_PKT_FRAME_LEN, o_buf); if (rc != 0) { LOG(WARNING) << "Wrong encode parameters"; std::fill(o_buf, o_buf + o_len, 0); } return HFP_LC3_PKT_FRAME_LEN; } } // namespace mmc
system/stack/mmc/codec_server/hfp_lc3_mmc_encoder.h 0 → 100644 +62 −0 Original line number Diff line number Diff line /* * Copyright 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MMC_CODEC_SERVER_HFP_LC3_MMC_ENCODER_H_ #define MMC_CODEC_SERVER_HFP_LC3_MMC_ENCODER_H_ #include "embdrv/lc3/include/lc3.h" #include "mmc/mmc_interface/mmc_interface.h" #include "mmc/proto/mmc_config.pb.h" namespace mmc { // Implementation of MmcInterface. // HfpLc3Encoder wraps lc3 encode libraries. class HfpLc3Encoder : public MmcInterface { public: explicit HfpLc3Encoder(); ~HfpLc3Encoder(); // HfpLc3Encoder is neither copyable nor movable. HfpLc3Encoder(const HfpLc3Encoder&) = delete; HfpLc3Encoder& operator=(const HfpLc3Encoder&) = delete; // Inits encoder instance. // // Returns: // Input pcm frame size accepted by the encoder, if init succeeded. // Negative errno on error, otherwise. int init(ConfigParam config) override; // Releases encoder instance. void cleanup() override; // Encodes data from |i_buf|, and stores the result to |o_buf|. // // Returns: // Encoded data length, if encode succeeded. // Negative errno on error, otherwise. int transcode(uint8_t* i_buf, int i_len, uint8_t* o_buf, int o_len) override; private: void* hfp_lc3_encoder_mem_; lc3_encoder_t hfp_lc3_encoder_; Lc3Param param_; }; } // namespace mmc #endif // MMC_CODEC_SERVER_HFP_LC3_MMC_ENCODER_H_