134 lines
3.6 KiB
C++
134 lines
3.6 KiB
C++
/*
|
|
* Lc3Config.cpp
|
|
*
|
|
* Copyright 2019 HIMSA II K/S - www.himsa.dk. 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.
|
|
*/
|
|
|
|
#include "Lc3Config.hpp"
|
|
#include <cmath>
|
|
|
|
Lc3Config::Lc3Config(uint16_t Fs_, FrameDuration N_ms_, uint8_t Nc_)
|
|
:
|
|
errorStatus(ERROR_FREE),
|
|
Fs(Fs_),
|
|
Fs_ind(getFs_ind(Fs)),
|
|
N_ms(N_ms_),
|
|
NF(getNF(Fs, N_ms_)),
|
|
NE(getNE(NF, N_ms_)),
|
|
Z( (N_ms==FrameDuration::d10ms) ? 3*NF/8 : 7*NF/30 ),
|
|
Nc(Nc_),
|
|
N_b( ((N_ms == Lc3Config::FrameDuration::d7p5ms) && (Fs==8000)) ? 60 : 64 )
|
|
{
|
|
if (0==Nc) // we do not restrict the maximum yet (naturally limited to 255 because of the chosen datatype)
|
|
{
|
|
errorStatus |= INVALID_NUMBER_OF_CHANNELS;
|
|
}
|
|
}
|
|
|
|
Lc3Config::~Lc3Config()
|
|
{
|
|
}
|
|
|
|
bool Lc3Config::isValid() const
|
|
{
|
|
return ERROR_FREE == errorStatus;
|
|
}
|
|
|
|
uint8_t Lc3Config::getErrorStatus() const
|
|
{
|
|
return errorStatus;
|
|
}
|
|
|
|
uint8_t Lc3Config::getFs_ind(uint16_t Fs)
|
|
{
|
|
uint8_t fs_ind=0;
|
|
switch(Fs)
|
|
{
|
|
case 8000: fs_ind=0; break;
|
|
case 16000: fs_ind=1; break;
|
|
case 24000: fs_ind=2; break;
|
|
case 32000: fs_ind=3; break;
|
|
case 44100:;
|
|
case 48000: fs_ind=4; break;
|
|
default:
|
|
errorStatus |= INVALID_SAMPLING_RATE;
|
|
}
|
|
return fs_ind;
|
|
}
|
|
|
|
|
|
uint16_t Lc3Config::getNF(uint16_t Fs, FrameDuration N_ms)
|
|
{
|
|
uint16_t NF = 80;
|
|
if (FrameDuration::d10ms == N_ms)
|
|
{
|
|
switch(Fs)
|
|
{
|
|
case 8000: NF=80; break;
|
|
case 16000: NF=160; break;
|
|
case 24000: NF=240; break;
|
|
case 32000: NF=320; break;
|
|
case 44100:;
|
|
case 48000: NF=480; break;
|
|
default :
|
|
errorStatus |= INVALID_SAMPLING_RATE;
|
|
}
|
|
}
|
|
else if (FrameDuration::d7p5ms == N_ms)
|
|
{
|
|
switch(Fs)
|
|
{
|
|
case 8000: NF=60; break;
|
|
case 16000: NF=120; break;
|
|
case 24000: NF=180; break;
|
|
case 32000: NF=240; break;
|
|
case 44100:;
|
|
case 48000: NF=360; break;
|
|
default :
|
|
errorStatus |= INVALID_SAMPLING_RATE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// We never should reach this line unless
|
|
// strange things happen. However, we want
|
|
// to be on the safe side and thus handle
|
|
// this case explicitly.
|
|
errorStatus |= INVALID_FRAME_DURATION;
|
|
}
|
|
return NF;
|
|
}
|
|
|
|
uint16_t Lc3Config::getNE(uint16_t NF, FrameDuration N_ms)
|
|
{
|
|
//3.3.4.3 Time-Frequency Transformation (d09r04_*implementorComments*)
|
|
if (FrameDuration::d10ms == N_ms)
|
|
{
|
|
return (480==NF) ? 400:NF;
|
|
}
|
|
else
|
|
{
|
|
return (360==NF) ? 300:NF;
|
|
}
|
|
}
|
|
|
|
uint16_t Lc3Config::getByteCountFromBitrate(uint32_t bitrate) const
|
|
{
|
|
// Section 3.25 Bit budget and bitrate (LC3_Specification_d09r06)
|
|
double f_scal = (44100==Fs)? 48000.0/44100.0 : 1.0;
|
|
double N_ms_value = (FrameDuration::d10ms == N_ms) ? 10.0 : 7.5;
|
|
return floor( (bitrate * N_ms_value * f_scal)/8000.0 );
|
|
}
|