1 /******************************************************************************
2  *
3  * Copyright (c) 2023 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  ******************************************************************************/
18 
19 #pragma once
20 
21 #include <bluetooth/log.h>
22 #include <stdint.h>
23 
24 #include <vector>
25 
26 #include "audio_hal_client/audio_hal_client.h"
27 #include "le_audio_types.h"
28 
29 namespace bluetooth::le_audio {
30 
31 /* CodecInterface provides a thin abstraction layer above the codec instance. It
32  * manages the output buffers internally and resizes them automatically when
33  * needed.
34  * Multi-channel stream encoding requires multiple CodecInterface instances, but
35  * even then it is still possible to encode the stream data into a single output
36  * buffer. Thanks to the optional parameters to the encode() method, the
37  * internal buffer of the first instance can be used as an output buffer by the
38  * second instance, as long as equal life time of both instances is guaranteed.
39  *
40  */
41 class CodecInterface {
42 public:
43   enum class Status {
44     STATUS_ERR_CODEC_NOT_READY = -128,
45     STATUS_ERR_INVALID_CODEC_ID = -127,
46     STATUS_ERR_CODING_ERROR = -1,
47     STATUS_OK = 0,
48   };
49 
50   CodecInterface(const types::LeAudioCodecId& codec_id);
51   virtual ~CodecInterface();
CreateInstance(const types::LeAudioCodecId & codec_id)52   static std::unique_ptr<CodecInterface> CreateInstance(const types::LeAudioCodecId& codec_id) {
53     return std::make_unique<CodecInterface>(codec_id);
54   }
55   virtual CodecInterface::Status InitEncoder(const LeAudioCodecConfiguration& pcm_config,
56                                              const LeAudioCodecConfiguration& codec_config);
57   virtual CodecInterface::Status InitDecoder(const LeAudioCodecConfiguration& codec_config,
58                                              const LeAudioCodecConfiguration& pcm_config);
59   virtual CodecInterface::Status Encode(const uint8_t* data, int stride, uint16_t out_size,
60                                         std::vector<int16_t>* out_buffer = nullptr,
61                                         uint16_t out_offset = 0);
62   virtual CodecInterface::Status Decode(uint8_t* data, uint16_t size);
63   virtual void Cleanup();
64   virtual bool IsReady();
65   virtual uint16_t GetNumOfSamplesPerChannel();
66   virtual uint8_t GetNumOfBytesPerSample();
67   virtual std::vector<int16_t>& GetDecodedSamples();
68 
69 private:
70   struct Impl;
71   Impl* impl;
72 };
73 
74 }  // namespace bluetooth::le_audio
75 
76 namespace std {
77 template <>
78 struct formatter<bluetooth::le_audio::CodecInterface::Status>
79     : enum_formatter<bluetooth::le_audio::CodecInterface::Status> {};
80 }  // namespace std
81