blob: cfb33df0eabb34f09965d8d4b415eb5c9d517948 [file] [log] [blame]
/*
* Copyright (c) [2015] Texas Instruments Incorporated
*
* All rights reserved not granted herein.
* Limited License.
*
* Texas Instruments Incorporated grants a world-wide, royalty-free,
* non-exclusive license under copyrights and patents it now or hereafter
* owns or controls to make, have made, use, import, offer to sell and sell ("Utilize")
* this software subject to the terms herein. With respect to the foregoing patent
*license, such license is granted solely to the extent that any such patent is necessary
* to Utilize the software alone. The patent license shall not apply to any combinations which
* include this software, other than combinations with devices manufactured by or for TI ("TI Devices").
* No hardware patent is licensed hereunder.
*
* Redistributions must preserve existing copyright notices and reproduce this license (including the
* above copyright notice and the disclaimer and (if applicable) source code license limitations below)
* in the documentation and/or other materials provided with the distribution
*
* Redistribution and use in binary form, without modification, are permitted provided that the
* following conditions are met:
*
* * No reverse engineering, decompilation, or disassembly of this software is permitted
* with respect to any software provided in binary form.
* * any redistribution and use are licensed by TI for use only with TI Devices.
* * Nothing shall obligate TI to provide you with source code for the software licensed
* and provided to you in object code.
*
* If software source code is provided to you, modification and redistribution of the source code are
* permitted provided that the following conditions are met:
*
* * any redistribution and use of the source code, including any resulting derivative works, are
* licensed by TI for use only with TI Devices.
* * any redistribution and use of any object code compiled from the source code and any resulting
* derivative works, are licensed by TI for use only with TI Devices.
*
* Neither the name of Texas Instruments Incorporated nor the names of its suppliers may be used to
* endorse or promote products derived from this software without specific prior written permission.
*
* DISCLAIMER.
*
* THIS SOFTWARE IS PROVIDED BY TI AND TI'S LICENSORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TI AND TI'S LICENSORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "RAS_lib.h"
static int16 PV_Dec;
static int8 SI_Dec;
#define NULL 0
#define PRED_CYPHER_CONST 0x3292
#define STEP_CYPHER_CONST 0x5438
#define HDR_NOT_SCRAMBLED 1
static uint8 ras_pec_mode;
static int16 per_buff[MAX_INPUT_BUF_SIZE*4];
const uint16 codec_stepsize_Lut[89] =
{
7, 8, 9, 10, 11, 12, 13, 14,
16, 17, 19, 21, 23, 25, 28, 31,
34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658,
724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493,10442,11487,12635,13899,
15289,16818,18500,20350,22385,24623,27086,29794, 32767
};
const int8 codec_IndexLut[16] =
{
-1, -1, -1, -1, 2, 4, 6, 8,
-1, -1, -1, -1, 2, 4, 6, 8
};
/**************************************************************************************************
*
* @fn codec_DecodeSingle
*
* @brief This routine decode a 4bits ADPCM sample to a uin16 PCM audio sample.
*
* @param uint8 a 4 bits ADPCM sample
*
*
* @return the 16 bits PCM samples.
*/
static int16 codec_DecodeSingle(uint8 codec_4bits)
{
int16 step = codec_stepsize_Lut[SI_Dec];
int16 cum_diff = step>>3;
// DBG("step %d cum_diff %d\n", step, cum_diff);
SI_Dec += codec_IndexLut[codec_4bits];
if(SI_Dec<0) SI_Dec = 0; else if(SI_Dec>88) SI_Dec = 88;
if(codec_4bits&4)
cum_diff += step;
if(codec_4bits&2)
cum_diff += step>>1;
if(codec_4bits&1)
cum_diff += step>>2;
if(codec_4bits&8)
{
if (PV_Dec < (-32767+cum_diff))
(PV_Dec) = -32767;
else
PV_Dec -= cum_diff;
}
else
{
if (PV_Dec > (0x7fff-cum_diff))
(PV_Dec) = 0x7fff;
else
PV_Dec += cum_diff;
}
return PV_Dec;
}
/**************************************************************************************************
*
* @fn codec_DecodeBuff
*
* @brief This routine encode a buffer with ADPCM IMA.
*
* @param int16* dst pointer to buffer where decoding result will be copy
* uint8* src input buffer, size must be a multiple of 4 bytes
* srcSize Number of byte that will be generated by the encoder (4* (src buffer size in byte))
*
*
* @return none
*/
static void codec_DecodeBuff(int16* dst, uint8* src, unsigned int srcSize, int8 *si, int16 *pv)
{
// calculate pointers to iterate output buffer
int16* out = dst;
int16* end = out+(srcSize>>1);
int16 temp;
PV_Dec = *pv;
SI_Dec = *si;
while(out<end)
{
// get byte from src
uint8 codec = *src;
// DBG("codec %04x\n", codec);
// *out++ = codec_DecodeSingle((codec&0xF)); // decode value and store it
temp = codec_DecodeSingle((codec&0xF)); // decode value and store it
// DBG("from low %04x\n", temp);
*out++ = temp;
codec >>= 4; // use high nibble of byte
codec &= 0xF; // use high nibble of byte
// *out++ = codec_DecodeSingle(codec); // decode value and store it
temp = codec_DecodeSingle((codec)); // decode value and store it
// DBG("from high %04x\n", temp);
*out++ = temp;
++src; // move on a byte for next sample
}
*pv = PV_Dec;
*si = SI_Dec;
}
/**************************************************************************************************
*
* @fn RAS_Init
*
* @brief RemoTI Audio Subsystem, initialization function
*
* input parameters
*
* @param pec_mode: Packet Error concealment algorithm to apply:
* RAS_NO_PEC(0): None (default)
* RAS_PEC_MODE1(1): Replace lost packets by last valid.
*
* output parameters
*codec_ima_DecodeBuff
* None.
*
* @return .
* status. 0 SUCCESS
* -1 ERROR: INVALID PARAMETER
*/
uint8 RAS_Init( uint8 pec_mode )
{
uint16 i;
if (pec_mode>RAS_PEC_MODE1) return -1;
ras_pec_mode = pec_mode;
for (i=0; i<(MAX_INPUT_BUF_SIZE*4);i++)
per_buff[i]=0;
return 0;
}
/**************************************************************************************************
*
* @fn RAS_GetVersion
*
* @brief RemoTI Audio Subsystem, retrieve software version
*
* input parameters
*
* none
*
* output parameters
*
* None.
*
* @return .
* Software Version. MSB Major revision number
* LSB: Minor revision number
*/
uint16 RAS_GetVersion( void )
{
return RAS_SOFTWARE_VERSION;
}
/**************************************************************************************************
*
* @fn RAS_Decode
*
* @brief RemoTI Audio Subsystem, decoding function. decode encoded audioframe to PCM samples.
*
* input parameters
*
* @param option: decoding option. can be pure decoding, or packet lot concealment algorithm:
* RAS_PACKET_LOST(0)
* RAS_DECODE(1)
* @param input: address of the buffer to decode, this buffer must include the 3 bytes header..
*
* @param inputLength: length of the buffer to decode, excluding the 3 bytes header.
* cannot be greater than 128 (MAX_INPUT_BUF_SIZE);
*
* output parameters
*
* @param output: buffer where the decoded PCM will be written. This buffer must be allocated by the caller.
* it must have a length of 4 times the inputLength variable
*
* @param outputLenght: length of the decoded buffer.
* max possible value 512 (4*MAX_INPUT_BUF_SIZE);
*
*
* @return .
* status. 0 SUCCESS
* -1 ERROR: INVALID PARAMETER
*
*/
uint8 RAS_Decode( uint8 option, uint8* input, uint16 inputLength, int16* output,uint16 *outputLenght )
{
int8 step_index;
int16 predicted_value;
uint16 i;
static uint8 *rf_DataFrame;
*outputLenght = 0;
// DBG("RAS_Decode option %d input %04x inputLength %d output %04x outputLength %d\n", option, input, inputLength, output, outputLenght);
if ((output == NULL) || (inputLength > MAX_INPUT_BUF_SIZE)) return -1;
#ifdef HDR_NOT_SCRAMBLED
predicted_value = (input [0] + ((input[1])<<8));
step_index = input [2] & 0xFF;
#else
predicted_value = (int16)(((int16)((input[0])<<8))+((int16)(input [2] ))) ^ PRED_CYPHER_CONST;
step_index = (input [1] & 0xFF) ^STEP_CYPHER_CONST;
#endif
//extract Predicted value and step index from the header.
inputLength-=3; //Remove Header Size
// check Option
switch(option)
{
case RAS_PACKET_LOST:
{
switch (ras_pec_mode)
{
case RAS_PEC_MODE1:
for (i=0; i<(inputLength*4);i++)
output[i] = per_buff[i];
break;
default:
break;
}
}
break;
case RAS_DECODE_TI_TYPE1:
if (input == NULL) return -1;
rf_DataFrame = input+3;
codec_DecodeBuff(output, rf_DataFrame, inputLength*4, &step_index, &predicted_value);
//Save Frame for packet error concealment
switch (ras_pec_mode)
{
case RAS_PEC_MODE1:
for (i=0; i<(inputLength*4);i++)
per_buff[i] = output[i];
break;
default:
break;
}
break;
default:
break;
}
*outputLenght = inputLength*4;
return 0;
};