1*49fe348cSAndroid Build Coastguard Worker /****************************************************************************** 2*49fe348cSAndroid Build Coastguard Worker * 3*49fe348cSAndroid Build Coastguard Worker * Copyright 2022 Google LLC 4*49fe348cSAndroid Build Coastguard Worker * 5*49fe348cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 6*49fe348cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 7*49fe348cSAndroid Build Coastguard Worker * You may obtain a copy of the License at: 8*49fe348cSAndroid Build Coastguard Worker * 9*49fe348cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 10*49fe348cSAndroid Build Coastguard Worker * 11*49fe348cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 12*49fe348cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 13*49fe348cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*49fe348cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 15*49fe348cSAndroid Build Coastguard Worker * limitations under the License. 16*49fe348cSAndroid Build Coastguard Worker * 17*49fe348cSAndroid Build Coastguard Worker ******************************************************************************/ 18*49fe348cSAndroid Build Coastguard Worker 19*49fe348cSAndroid Build Coastguard Worker /** 20*49fe348cSAndroid Build Coastguard Worker * Low Complexity Communication Codec (LC3) - C++ interface 21*49fe348cSAndroid Build Coastguard Worker */ 22*49fe348cSAndroid Build Coastguard Worker 23*49fe348cSAndroid Build Coastguard Worker #ifndef __LC3_CPP_H 24*49fe348cSAndroid Build Coastguard Worker #define __LC3_CPP_H 25*49fe348cSAndroid Build Coastguard Worker 26*49fe348cSAndroid Build Coastguard Worker #include <cassert> 27*49fe348cSAndroid Build Coastguard Worker #include <memory> 28*49fe348cSAndroid Build Coastguard Worker #include <vector> 29*49fe348cSAndroid Build Coastguard Worker #include <stdlib.h> 30*49fe348cSAndroid Build Coastguard Worker 31*49fe348cSAndroid Build Coastguard Worker #include "lc3.h" 32*49fe348cSAndroid Build Coastguard Worker 33*49fe348cSAndroid Build Coastguard Worker namespace lc3 { 34*49fe348cSAndroid Build Coastguard Worker 35*49fe348cSAndroid Build Coastguard Worker // PCM Sample Format 36*49fe348cSAndroid Build Coastguard Worker // - Signed 16 bits, in 16 bits words (int16_t) 37*49fe348cSAndroid Build Coastguard Worker // - Signed 24 bits, using low three bytes of 32 bits words (int32_t) 38*49fe348cSAndroid Build Coastguard Worker // The high byte sign extends (bits 31..24 set to b23) 39*49fe348cSAndroid Build Coastguard Worker // - Signed 24 bits packed in 3 bytes little endian 40*49fe348cSAndroid Build Coastguard Worker // - Floating point 32 bits (float type), in range -1 to 1 41*49fe348cSAndroid Build Coastguard Worker 42*49fe348cSAndroid Build Coastguard Worker enum class PcmFormat { 43*49fe348cSAndroid Build Coastguard Worker kS16 = LC3_PCM_FORMAT_S16, 44*49fe348cSAndroid Build Coastguard Worker kS24 = LC3_PCM_FORMAT_S24, 45*49fe348cSAndroid Build Coastguard Worker kS24In3Le = LC3_PCM_FORMAT_S24_3LE, 46*49fe348cSAndroid Build Coastguard Worker kF32 = LC3_PCM_FORMAT_FLOAT 47*49fe348cSAndroid Build Coastguard Worker }; 48*49fe348cSAndroid Build Coastguard Worker 49*49fe348cSAndroid Build Coastguard Worker // Base Encoder/Decoder Class 50*49fe348cSAndroid Build Coastguard Worker template <typename T> 51*49fe348cSAndroid Build Coastguard Worker class Base { 52*49fe348cSAndroid Build Coastguard Worker protected: Base(int dt_us,int sr_hz,int sr_pcm_hz,size_t nchannels,bool hrmode)53*49fe348cSAndroid Build Coastguard Worker Base(int dt_us, int sr_hz, int sr_pcm_hz, size_t nchannels, bool hrmode) 54*49fe348cSAndroid Build Coastguard Worker : dt_us_(dt_us), 55*49fe348cSAndroid Build Coastguard Worker sr_hz_(sr_hz), 56*49fe348cSAndroid Build Coastguard Worker sr_pcm_hz_(sr_pcm_hz == 0 ? sr_hz : sr_pcm_hz), 57*49fe348cSAndroid Build Coastguard Worker nchannels_(nchannels), 58*49fe348cSAndroid Build Coastguard Worker hrmode_(hrmode) { 59*49fe348cSAndroid Build Coastguard Worker states.reserve(nchannels_); 60*49fe348cSAndroid Build Coastguard Worker } 61*49fe348cSAndroid Build Coastguard Worker 62*49fe348cSAndroid Build Coastguard Worker virtual ~Base() = default; 63*49fe348cSAndroid Build Coastguard Worker 64*49fe348cSAndroid Build Coastguard Worker int dt_us_, sr_hz_; 65*49fe348cSAndroid Build Coastguard Worker int sr_pcm_hz_; 66*49fe348cSAndroid Build Coastguard Worker size_t nchannels_; 67*49fe348cSAndroid Build Coastguard Worker bool hrmode_; 68*49fe348cSAndroid Build Coastguard Worker 69*49fe348cSAndroid Build Coastguard Worker using state_ptr = std::unique_ptr<T, decltype(&free)>; 70*49fe348cSAndroid Build Coastguard Worker std::vector<state_ptr> states; 71*49fe348cSAndroid Build Coastguard Worker 72*49fe348cSAndroid Build Coastguard Worker public: 73*49fe348cSAndroid Build Coastguard Worker // Return the number of PCM samples in a frame GetFrameSamples()74*49fe348cSAndroid Build Coastguard Worker int GetFrameSamples() { 75*49fe348cSAndroid Build Coastguard Worker return lc3_hr_frame_samples(hrmode_, dt_us_, sr_pcm_hz_); } 76*49fe348cSAndroid Build Coastguard Worker 77*49fe348cSAndroid Build Coastguard Worker // Return the size of a frame block, from bitrate GetFrameBytes(int bitrate)78*49fe348cSAndroid Build Coastguard Worker int GetFrameBytes(int bitrate) { 79*49fe348cSAndroid Build Coastguard Worker return lc3_hr_frame_block_bytes( 80*49fe348cSAndroid Build Coastguard Worker hrmode_, dt_us_, sr_hz_, nchannels_, bitrate); } 81*49fe348cSAndroid Build Coastguard Worker 82*49fe348cSAndroid Build Coastguard Worker // Resolve the bitrate, from the size of frame blocks ResolveBitrate(int nbytes)83*49fe348cSAndroid Build Coastguard Worker int ResolveBitrate(int nbytes) { 84*49fe348cSAndroid Build Coastguard Worker return lc3_hr_resolve_bitrate(hrmode_, dt_us_, sr_hz_, nbytes); } 85*49fe348cSAndroid Build Coastguard Worker 86*49fe348cSAndroid Build Coastguard Worker // Return algorithmic delay, as a number of samples GetDelaySamples()87*49fe348cSAndroid Build Coastguard Worker int GetDelaySamples() { 88*49fe348cSAndroid Build Coastguard Worker return lc3_hr_delay_samples(hrmode_, dt_us_, sr_pcm_hz_); } 89*49fe348cSAndroid Build Coastguard Worker 90*49fe348cSAndroid Build Coastguard Worker }; // class Base 91*49fe348cSAndroid Build Coastguard Worker 92*49fe348cSAndroid Build Coastguard Worker // Encoder Class 93*49fe348cSAndroid Build Coastguard Worker class Encoder : public Base<struct lc3_encoder> { 94*49fe348cSAndroid Build Coastguard Worker template <typename T> EncodeImpl(PcmFormat fmt,const T * pcm,int block_size,uint8_t * out)95*49fe348cSAndroid Build Coastguard Worker int EncodeImpl(PcmFormat fmt, const T *pcm, int block_size, uint8_t *out) { 96*49fe348cSAndroid Build Coastguard Worker if (states.size() != nchannels_) return -1; 97*49fe348cSAndroid Build Coastguard Worker 98*49fe348cSAndroid Build Coastguard Worker enum lc3_pcm_format cfmt = static_cast<lc3_pcm_format>(fmt); 99*49fe348cSAndroid Build Coastguard Worker int ret = 0; 100*49fe348cSAndroid Build Coastguard Worker 101*49fe348cSAndroid Build Coastguard Worker uint8_t *out_ptr = out; 102*49fe348cSAndroid Build Coastguard Worker for (size_t ich = 0; ich < nchannels_; ich++) { 103*49fe348cSAndroid Build Coastguard Worker int frame_size = block_size / nchannels_ 104*49fe348cSAndroid Build Coastguard Worker + (ich < block_size % nchannels_); 105*49fe348cSAndroid Build Coastguard Worker 106*49fe348cSAndroid Build Coastguard Worker ret |= lc3_encode(states[ich].get(), cfmt, pcm + ich, nchannels_, 107*49fe348cSAndroid Build Coastguard Worker frame_size, out_ptr); 108*49fe348cSAndroid Build Coastguard Worker 109*49fe348cSAndroid Build Coastguard Worker out_ptr += frame_size; 110*49fe348cSAndroid Build Coastguard Worker } 111*49fe348cSAndroid Build Coastguard Worker 112*49fe348cSAndroid Build Coastguard Worker return ret; 113*49fe348cSAndroid Build Coastguard Worker } 114*49fe348cSAndroid Build Coastguard Worker 115*49fe348cSAndroid Build Coastguard Worker public: 116*49fe348cSAndroid Build Coastguard Worker // Encoder construction / destruction 117*49fe348cSAndroid Build Coastguard Worker // 118*49fe348cSAndroid Build Coastguard Worker // The frame duration `dt_us` is 2500, 5000, 7500 or 10000 us. 119*49fe348cSAndroid Build Coastguard Worker // The sample rate `sr_hz` is 8000, 16000, 24000, 32000 or 48000 Hz. 120*49fe348cSAndroid Build Coastguard Worker // The `hrmode` flag enables the high-resolution mode, in which case 121*49fe348cSAndroid Build Coastguard Worker // the sample rate is 48000 or 96000 Hz. 122*49fe348cSAndroid Build Coastguard Worker // 123*49fe348cSAndroid Build Coastguard Worker // The `sr_pcm_hz` parameter is a downsampling option of PCM input, 124*49fe348cSAndroid Build Coastguard Worker // the value 0 fallback to the sample rate of the encoded stream `sr_hz`. 125*49fe348cSAndroid Build Coastguard Worker // When used, `sr_pcm_hz` is intended to be higher or equal to the encoder 126*49fe348cSAndroid Build Coastguard Worker // sample rate `sr_hz`. 127*49fe348cSAndroid Build Coastguard Worker 128*49fe348cSAndroid Build Coastguard Worker Encoder(int dt_us, int sr_hz, int sr_pcm_hz = 0, 129*49fe348cSAndroid Build Coastguard Worker size_t nchannels = 1, bool hrmode = false) Base(dt_us,sr_hz,sr_pcm_hz,nchannels,hrmode)130*49fe348cSAndroid Build Coastguard Worker : Base(dt_us, sr_hz, sr_pcm_hz, nchannels, hrmode) { 131*49fe348cSAndroid Build Coastguard Worker for (size_t ich = 0; ich < nchannels_; ich++) { 132*49fe348cSAndroid Build Coastguard Worker auto s = state_ptr((lc3_encoder_t) 133*49fe348cSAndroid Build Coastguard Worker malloc(lc3_hr_encoder_size(hrmode_, dt_us_, sr_pcm_hz_)), free); 134*49fe348cSAndroid Build Coastguard Worker 135*49fe348cSAndroid Build Coastguard Worker if (lc3_hr_setup_encoder(hrmode_, dt_us_, sr_hz_, sr_pcm_hz_, s.get())) 136*49fe348cSAndroid Build Coastguard Worker states.push_back(std::move(s)); 137*49fe348cSAndroid Build Coastguard Worker } 138*49fe348cSAndroid Build Coastguard Worker } 139*49fe348cSAndroid Build Coastguard Worker 140*49fe348cSAndroid Build Coastguard Worker ~Encoder() override = default; 141*49fe348cSAndroid Build Coastguard Worker 142*49fe348cSAndroid Build Coastguard Worker // Reset encoder state 143*49fe348cSAndroid Build Coastguard Worker Reset()144*49fe348cSAndroid Build Coastguard Worker void Reset() { 145*49fe348cSAndroid Build Coastguard Worker for (auto &s : states) 146*49fe348cSAndroid Build Coastguard Worker lc3_hr_setup_encoder(hrmode_, dt_us_, sr_hz_, sr_pcm_hz_, s.get()); 147*49fe348cSAndroid Build Coastguard Worker } 148*49fe348cSAndroid Build Coastguard Worker 149*49fe348cSAndroid Build Coastguard Worker // Encode 150*49fe348cSAndroid Build Coastguard Worker // 151*49fe348cSAndroid Build Coastguard Worker // The input PCM samples are given in signed 16 bits, 24 bits, float, 152*49fe348cSAndroid Build Coastguard Worker // according the type of `pcm` input buffer, or by selecting a format. 153*49fe348cSAndroid Build Coastguard Worker // 154*49fe348cSAndroid Build Coastguard Worker // The PCM samples are read in interleaved way, and consecutive 155*49fe348cSAndroid Build Coastguard Worker // `nchannels` frames, are output in `out` buffer, of size `buffer_size`. 156*49fe348cSAndroid Build Coastguard Worker // 157*49fe348cSAndroid Build Coastguard Worker // The value returned is 0 on successs, -1 otherwise. 158*49fe348cSAndroid Build Coastguard Worker Encode(const int16_t * pcm,int block_size,uint8_t * out)159*49fe348cSAndroid Build Coastguard Worker int Encode(const int16_t *pcm, int block_size, uint8_t *out) { 160*49fe348cSAndroid Build Coastguard Worker return EncodeImpl(PcmFormat::kS16, pcm, block_size, out); 161*49fe348cSAndroid Build Coastguard Worker } 162*49fe348cSAndroid Build Coastguard Worker Encode(const int32_t * pcm,int block_size,uint8_t * out)163*49fe348cSAndroid Build Coastguard Worker int Encode(const int32_t *pcm, int block_size, uint8_t *out) { 164*49fe348cSAndroid Build Coastguard Worker return EncodeImpl(PcmFormat::kS24, pcm, block_size, out); 165*49fe348cSAndroid Build Coastguard Worker } 166*49fe348cSAndroid Build Coastguard Worker Encode(const float * pcm,int block_size,uint8_t * out)167*49fe348cSAndroid Build Coastguard Worker int Encode(const float *pcm, int block_size, uint8_t *out) { 168*49fe348cSAndroid Build Coastguard Worker return EncodeImpl(PcmFormat::kF32, pcm, block_size, out); 169*49fe348cSAndroid Build Coastguard Worker } 170*49fe348cSAndroid Build Coastguard Worker Encode(PcmFormat fmt,const void * pcm,int block_size,uint8_t * out)171*49fe348cSAndroid Build Coastguard Worker int Encode(PcmFormat fmt, const void *pcm, int block_size, uint8_t *out) { 172*49fe348cSAndroid Build Coastguard Worker uintptr_t pcm_ptr = reinterpret_cast<uintptr_t>(pcm); 173*49fe348cSAndroid Build Coastguard Worker 174*49fe348cSAndroid Build Coastguard Worker switch (fmt) { 175*49fe348cSAndroid Build Coastguard Worker case PcmFormat::kS16: 176*49fe348cSAndroid Build Coastguard Worker assert(pcm_ptr % alignof(int16_t) == 0); 177*49fe348cSAndroid Build Coastguard Worker return EncodeImpl(fmt, reinterpret_cast<const int16_t *>(pcm), 178*49fe348cSAndroid Build Coastguard Worker block_size, out); 179*49fe348cSAndroid Build Coastguard Worker 180*49fe348cSAndroid Build Coastguard Worker case PcmFormat::kS24: 181*49fe348cSAndroid Build Coastguard Worker assert(pcm_ptr % alignof(int32_t) == 0); 182*49fe348cSAndroid Build Coastguard Worker return EncodeImpl(fmt, reinterpret_cast<const int32_t *>(pcm), 183*49fe348cSAndroid Build Coastguard Worker block_size, out); 184*49fe348cSAndroid Build Coastguard Worker 185*49fe348cSAndroid Build Coastguard Worker case PcmFormat::kS24In3Le: 186*49fe348cSAndroid Build Coastguard Worker return EncodeImpl(fmt, reinterpret_cast<const int8_t(*)[3]>(pcm), 187*49fe348cSAndroid Build Coastguard Worker block_size, out); 188*49fe348cSAndroid Build Coastguard Worker 189*49fe348cSAndroid Build Coastguard Worker case PcmFormat::kF32: 190*49fe348cSAndroid Build Coastguard Worker assert(pcm_ptr % alignof(float) == 0); 191*49fe348cSAndroid Build Coastguard Worker return EncodeImpl(fmt, reinterpret_cast<const float *>(pcm), block_size, 192*49fe348cSAndroid Build Coastguard Worker out); 193*49fe348cSAndroid Build Coastguard Worker } 194*49fe348cSAndroid Build Coastguard Worker 195*49fe348cSAndroid Build Coastguard Worker return -1; 196*49fe348cSAndroid Build Coastguard Worker } 197*49fe348cSAndroid Build Coastguard Worker 198*49fe348cSAndroid Build Coastguard Worker }; // class Encoder 199*49fe348cSAndroid Build Coastguard Worker 200*49fe348cSAndroid Build Coastguard Worker // Decoder Class 201*49fe348cSAndroid Build Coastguard Worker class Decoder : public Base<struct lc3_decoder> { 202*49fe348cSAndroid Build Coastguard Worker template <typename T> DecodeImpl(const uint8_t * in,int block_size,PcmFormat fmt,T * pcm)203*49fe348cSAndroid Build Coastguard Worker int DecodeImpl(const uint8_t *in, int block_size, PcmFormat fmt, T *pcm) { 204*49fe348cSAndroid Build Coastguard Worker if (states.size() != nchannels_) return -1; 205*49fe348cSAndroid Build Coastguard Worker 206*49fe348cSAndroid Build Coastguard Worker enum lc3_pcm_format cfmt = static_cast<enum lc3_pcm_format>(fmt); 207*49fe348cSAndroid Build Coastguard Worker int ret = 0; 208*49fe348cSAndroid Build Coastguard Worker 209*49fe348cSAndroid Build Coastguard Worker const uint8_t *in_ptr = in; 210*49fe348cSAndroid Build Coastguard Worker for (size_t ich = 0; ich < nchannels_; ich++) { 211*49fe348cSAndroid Build Coastguard Worker int frame_size = block_size / nchannels_ 212*49fe348cSAndroid Build Coastguard Worker + (ich < block_size % nchannels_); 213*49fe348cSAndroid Build Coastguard Worker 214*49fe348cSAndroid Build Coastguard Worker ret |= lc3_decode(states[ich].get(), in_ptr, frame_size, 215*49fe348cSAndroid Build Coastguard Worker cfmt, pcm + ich, nchannels_); 216*49fe348cSAndroid Build Coastguard Worker 217*49fe348cSAndroid Build Coastguard Worker in_ptr += frame_size; 218*49fe348cSAndroid Build Coastguard Worker } 219*49fe348cSAndroid Build Coastguard Worker 220*49fe348cSAndroid Build Coastguard Worker return ret; 221*49fe348cSAndroid Build Coastguard Worker } 222*49fe348cSAndroid Build Coastguard Worker 223*49fe348cSAndroid Build Coastguard Worker public: 224*49fe348cSAndroid Build Coastguard Worker // Decoder construction / destruction 225*49fe348cSAndroid Build Coastguard Worker // 226*49fe348cSAndroid Build Coastguard Worker // The frame duration `dt_us` is 2500, 5000, 7500 or 10000 us. 227*49fe348cSAndroid Build Coastguard Worker // The sample rate `sr_hz` is 8000, 16000, 24000, 32000 or 48000 Hz. 228*49fe348cSAndroid Build Coastguard Worker // The `hrmode` flag enables the high-resolution mode, in which case 229*49fe348cSAndroid Build Coastguard Worker // the sample rate is 48000 or 96000 Hz. 230*49fe348cSAndroid Build Coastguard Worker // 231*49fe348cSAndroid Build Coastguard Worker // The `sr_pcm_hz` parameter is an downsampling option of PCM output, 232*49fe348cSAndroid Build Coastguard Worker // the value 0 fallback to the sample rate of the decoded stream `sr_hz`. 233*49fe348cSAndroid Build Coastguard Worker // When used, `sr_pcm_hz` is intended to be higher or equal to the decoder 234*49fe348cSAndroid Build Coastguard Worker // sample rate `sr_hz`. 235*49fe348cSAndroid Build Coastguard Worker 236*49fe348cSAndroid Build Coastguard Worker Decoder(int dt_us, int sr_hz, int sr_pcm_hz = 0, 237*49fe348cSAndroid Build Coastguard Worker size_t nchannels = 1, bool hrmode = false) Base(dt_us,sr_hz,sr_pcm_hz,nchannels,hrmode)238*49fe348cSAndroid Build Coastguard Worker : Base(dt_us, sr_hz, sr_pcm_hz, nchannels, hrmode) { 239*49fe348cSAndroid Build Coastguard Worker for (size_t i = 0; i < nchannels_; i++) { 240*49fe348cSAndroid Build Coastguard Worker auto s = state_ptr((lc3_decoder_t) 241*49fe348cSAndroid Build Coastguard Worker malloc(lc3_hr_decoder_size(hrmode_, dt_us_, sr_pcm_hz_)), free); 242*49fe348cSAndroid Build Coastguard Worker 243*49fe348cSAndroid Build Coastguard Worker if (lc3_hr_setup_decoder(hrmode_, dt_us_, sr_hz_, sr_pcm_hz_, s.get())) 244*49fe348cSAndroid Build Coastguard Worker states.push_back(std::move(s)); 245*49fe348cSAndroid Build Coastguard Worker } 246*49fe348cSAndroid Build Coastguard Worker } 247*49fe348cSAndroid Build Coastguard Worker 248*49fe348cSAndroid Build Coastguard Worker ~Decoder() override = default; 249*49fe348cSAndroid Build Coastguard Worker 250*49fe348cSAndroid Build Coastguard Worker // Reset decoder state 251*49fe348cSAndroid Build Coastguard Worker Reset()252*49fe348cSAndroid Build Coastguard Worker void Reset() { 253*49fe348cSAndroid Build Coastguard Worker for (auto &s : states) 254*49fe348cSAndroid Build Coastguard Worker lc3_hr_setup_decoder(hrmode_, dt_us_, sr_hz_, sr_pcm_hz_, s.get()); 255*49fe348cSAndroid Build Coastguard Worker } 256*49fe348cSAndroid Build Coastguard Worker 257*49fe348cSAndroid Build Coastguard Worker // Decode 258*49fe348cSAndroid Build Coastguard Worker // 259*49fe348cSAndroid Build Coastguard Worker // Decode a frame block of size `block_size`, 260*49fe348cSAndroid Build Coastguard Worker // in the `pcm` buffer in interleaved way. 261*49fe348cSAndroid Build Coastguard Worker // 262*49fe348cSAndroid Build Coastguard Worker // The PCM samples are output in signed 16 bits, 24 bits, float, 263*49fe348cSAndroid Build Coastguard Worker // according the type of `pcm` output buffer, or by selecting a format. 264*49fe348cSAndroid Build Coastguard Worker // 265*49fe348cSAndroid Build Coastguard Worker // The value returned is 0 on successs, 1 when PLC has been performed, 266*49fe348cSAndroid Build Coastguard Worker // and -1 otherwise. 267*49fe348cSAndroid Build Coastguard Worker Decode(const uint8_t * in,int block_size,int16_t * pcm)268*49fe348cSAndroid Build Coastguard Worker int Decode(const uint8_t *in, int block_size, int16_t *pcm) { 269*49fe348cSAndroid Build Coastguard Worker return DecodeImpl(in, block_size, PcmFormat::kS16, pcm); 270*49fe348cSAndroid Build Coastguard Worker } 271*49fe348cSAndroid Build Coastguard Worker Decode(const uint8_t * in,int block_size,int32_t * pcm)272*49fe348cSAndroid Build Coastguard Worker int Decode(const uint8_t *in, int block_size, int32_t *pcm) { 273*49fe348cSAndroid Build Coastguard Worker return DecodeImpl(in, block_size, PcmFormat::kS24In3Le, pcm); 274*49fe348cSAndroid Build Coastguard Worker } 275*49fe348cSAndroid Build Coastguard Worker Decode(const uint8_t * in,int block_size,float * pcm)276*49fe348cSAndroid Build Coastguard Worker int Decode(const uint8_t *in, int block_size, float *pcm) { 277*49fe348cSAndroid Build Coastguard Worker return DecodeImpl(in, block_size, PcmFormat::kF32, pcm); 278*49fe348cSAndroid Build Coastguard Worker } 279*49fe348cSAndroid Build Coastguard Worker Decode(const uint8_t * in,int block_size,PcmFormat fmt,void * pcm)280*49fe348cSAndroid Build Coastguard Worker int Decode(const uint8_t *in, int block_size, PcmFormat fmt, void *pcm) { 281*49fe348cSAndroid Build Coastguard Worker uintptr_t pcm_ptr = reinterpret_cast<uintptr_t>(pcm); 282*49fe348cSAndroid Build Coastguard Worker 283*49fe348cSAndroid Build Coastguard Worker switch (fmt) { 284*49fe348cSAndroid Build Coastguard Worker case PcmFormat::kS16: 285*49fe348cSAndroid Build Coastguard Worker assert(pcm_ptr % alignof(int16_t) == 0); 286*49fe348cSAndroid Build Coastguard Worker return DecodeImpl(in, block_size, fmt, 287*49fe348cSAndroid Build Coastguard Worker reinterpret_cast<int16_t *>(pcm)); 288*49fe348cSAndroid Build Coastguard Worker 289*49fe348cSAndroid Build Coastguard Worker case PcmFormat::kS24: 290*49fe348cSAndroid Build Coastguard Worker assert(pcm_ptr % alignof(int32_t) == 0); 291*49fe348cSAndroid Build Coastguard Worker return DecodeImpl(in, block_size, fmt, 292*49fe348cSAndroid Build Coastguard Worker reinterpret_cast<int32_t *>(pcm)); 293*49fe348cSAndroid Build Coastguard Worker 294*49fe348cSAndroid Build Coastguard Worker case PcmFormat::kS24In3Le: 295*49fe348cSAndroid Build Coastguard Worker return DecodeImpl(in, block_size, fmt, 296*49fe348cSAndroid Build Coastguard Worker reinterpret_cast<int8_t(*)[3]>(pcm)); 297*49fe348cSAndroid Build Coastguard Worker 298*49fe348cSAndroid Build Coastguard Worker case PcmFormat::kF32: 299*49fe348cSAndroid Build Coastguard Worker assert(pcm_ptr % alignof(float) == 0); 300*49fe348cSAndroid Build Coastguard Worker return DecodeImpl(in, block_size, fmt, reinterpret_cast<float *>(pcm)); 301*49fe348cSAndroid Build Coastguard Worker } 302*49fe348cSAndroid Build Coastguard Worker 303*49fe348cSAndroid Build Coastguard Worker return -1; 304*49fe348cSAndroid Build Coastguard Worker } 305*49fe348cSAndroid Build Coastguard Worker 306*49fe348cSAndroid Build Coastguard Worker }; // class Decoder 307*49fe348cSAndroid Build Coastguard Worker 308*49fe348cSAndroid Build Coastguard Worker } // namespace lc3 309*49fe348cSAndroid Build Coastguard Worker 310*49fe348cSAndroid Build Coastguard Worker #endif /* __LC3_CPP_H */ 311