| /* |
| * Lc3Encoder.hpp |
| * |
| * Copyright 2021 HIMSA II K/S - www.himsa.com. Represented by EHIMA - |
| * www.ehima.com |
| * |
| * 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 API_LC3ENCODER_HPP_ |
| #define API_LC3ENCODER_HPP_ |
| |
| #include <cstdint> |
| #include <vector> |
| |
| #include "Lc3Config.hpp" |
| |
| /* |
| * Forward declaration of the "internal" class EncoderTop, so |
| * that the private vector of single channel encoders can be declared in |
| * Lc3Encoder. |
| */ |
| namespace Lc3Enc { |
| class EncoderTop; |
| } |
| |
| /* |
| * The LC3 encoder interface is specified in |
| * LC3 specification Sections 2.2 "Encoder interfaces" (dr09r07). |
| * |
| * Lc3Encoder is designed such that all specified features are provided |
| * with the (current) exception of not providing other input bit depth |
| * than 16 bit/sample. At the time of writing, the main purpose of the |
| * implementation was to handle 16bit audio data provided within android |
| * smartphones. Providing the specified 24bit and 32 bit audio data input, |
| * would make the API more complex. However, the main argument to not support |
| * these sample rates right now, is that internal operations and memory |
| * consumption would have to be increased measurable otherwise. |
| * |
| * Instantiating Lc3Encoder implies providing a Lc3Config instance. A copy of |
| * this instance is available as public const member so that all essential |
| * session parameters can be obtained throughout the lifetime of the Lc3Encoder |
| * instance. |
| * |
| * There is no possibility of changing Lc3Config within Lc3Encoder. When session |
| * parameters have to be changed, the calling application has to create a new |
| * instance of Lc3Encoder. |
| * |
| * Lc3 supports operation with variable encoded bitrate. It is possible to |
| * change the bitrate from frame to frame, where for preciseness the parameter |
| * is not given as bit rate directly but in terms of the byte_count per frame. |
| * This parameter has to be in the range of 20 to 400 (see LC3 specification |
| * Section 3.2.5 "Bit budget and bitrate") |
| * |
| */ |
| |
| class Lc3Encoder { |
| public: |
| /* |
| * Convenience constructor of Lc3Encoder with one simple parameter only. |
| * Note that this constructor instantiated Lc3Config implicitly with |
| * Lc3Config(Fs, Lc3Config::FrameDuration::d10ms, 1) that means that this |
| * constructor provides processing of one channel (mono) with 10ms frame |
| * duration. |
| * |
| * Parameters: |
| * Fs : Sampling frequency in Hz -> see Lc3Config.hpp for supported values |
| */ |
| Lc3Encoder(uint16_t Fs); |
| |
| /* |
| * General constructor of Lc3Encoder. |
| * |
| * Parameters: |
| * lc3Config_ : instance of Lc3Config. See documentation of Lc3Config for |
| * more details. Note: providing an invalid instance of Lc3Config will result |
| * in skipping any processing later. |
| * The provided instance of Lc3Config will be copied to the |
| * public field "lc3Config" (see below). |
| * |
| * bits_per_audio_sample_enc_ : The bits per audio sample for the input PCM |
| * signal. See LC3 specification Section 2.2 "Encoder interfaces" and |
| * Section 3.2.3 "Bits per sample" for the general LC3 requirement to support |
| * 16, 24 and 32 bit. Note: This parameter may differ from the decoder output |
| * PCM setting "bits_per_audio_sample_dec". |
| * |
| * However, the current implementation allows |
| * 16 bit only and will return an error INVALID_BITS_PER_AUDIO_SAMPLE for |
| * run() when configured with any other value. (see reasoning for this |
| * constraint in the general class descripton above) |
| * |
| * datapoints : pointer to an instance of a class allowing to collect internal |
| * data. Note: this feature is used and prepared for testing of the codec |
| * implementation only. See general "Readme.txt" |
| */ |
| Lc3Encoder(Lc3Config lc3Config_, uint8_t bits_per_audio_sample_enc_ = 16, |
| void* datapoints = nullptr); |
| |
| // no default constructor supported |
| Lc3Encoder() = delete; |
| |
| // Destructor |
| virtual ~Lc3Encoder(); |
| |
| /* |
| * Configuration provided during instantiation accessible as public const |
| * fields. Note: Lc3Config provides a getter to check whether the |
| * configuration is valid. |
| */ |
| const Lc3Config lc3Config; |
| const uint8_t bits_per_audio_sample_enc; |
| |
| // encoding errors (see return values of "run" methods) |
| static const uint8_t ERROR_FREE = 0x00; |
| static const uint8_t INVALID_CONFIGURATION = 0x01; |
| static const uint8_t INVALID_BYTE_COUNT = 0x02; |
| static const uint8_t INVALID_BITS_PER_AUDIO_SAMPLE = 0x03; |
| static const uint8_t ENCODER_ALLOCATION_ERROR = 0x04; |
| |
| /* |
| * Encoding of one input frame for one channel. |
| * |
| * Note that this method can be used for multi-channel configurations as well, |
| * particularly when the provided multi-channel "run" (see below) is not |
| * providing the kind of byte stream concatenation desired by a specific |
| * application. |
| * |
| * Parameters: |
| * x : pointer to input signal array with 16bit/sample. |
| * The length of the signal to be provided depends on the given |
| * session configuration and can be obtained via |
| * lc3Config.NF |
| * |
| * byte_count : determines the compression strength (-> bitrate) to be used |
| * for this specific frame. Supported values are 20 bytes to 400 |
| * bytes, where values well below 40 bytes typically give rather poor audio |
| * quality. Note: in case of having an application targeting a given bitrate, |
| * the helper method "lc3Config.getByteCountFromBitrate(.)" can be used to |
| * compute the proper setting for this byte_count parameter. |
| * |
| * bytes : pointer to byte array (memory) provided by the application, |
| * where the encoded byte stream will be placed. The size of this memory is |
| * given by the byte_count parameter. |
| * |
| * channelNr : index of channel to be processed (default=0), where channelNr |
| * < lc3Config.Nc |
| * |
| * Return value: error code as listed above. |
| */ |
| uint8_t run(const int16_t* x, uint16_t byte_count, uint8_t* bytes, |
| uint8_t channelNr = 0); |
| |
| /* |
| * Encoding of one multi-channel frame. |
| * |
| * Note that this call always processes all channels configured in the given |
| * session. |
| * |
| * Parameters: |
| * x : pointer to input signal array with 16bit/sample. |
| * The length of the signal to be provided depends on the given |
| * session configuration and can be obtained via |
| * lc3Config.NF * lc3Config.Nc |
| * |
| * byte_count_per_channel : determines the compression strength (-> bitrate) |
| * to be used for each channel individually of this specific frame. Thus, |
| * byte_count_per_channel is an array of byte_count values with length |
| * lc3Conig.Nc Supported values per channel are 20 bytes to 400 bytes. See |
| * also the documentation for the single channel "run" above. |
| * |
| * bytes : pointer to byte array (memory) provided by the application, |
| * where the encoded byte stream will be placed. The size of this memory is |
| * given by the byte_count_per_channel parameter, specifically by the sum of |
| * all channel-wise byte_count values (byte_count_per_channel[0] + ... + |
| * byte_count_per_channel[lc3Config.Nc]) This implies that the encoded bytes |
| * from the individual channels are concatenated directly (without any |
| * stuffing bytes or meta information). |
| * |
| * Return value: error code as listed above. |
| */ |
| uint8_t run(const int16_t* x, const uint16_t* byte_count_per_channel, |
| uint8_t* bytes); |
| |
| private: |
| std::vector<Lc3Enc::EncoderTop*> encoderList; |
| }; |
| |
| #endif /* API_LC3ENCODER_HPP_ */ |