📄 spclidg.c
字号:
/*-------------------------------------------------------------------------*
* *
* THIS IS AN UNPUBLISHED WORK CONTAINING CONFIDENTIAL AND PROPRIETARY *
* INFORMATION. IF PUBLICATION OCCURS, THE FOLLOWING NOTICE APPLIES: *
* "COPYRIGHT 2002 MIKET DSP SOLUTIONS, ALL RIGHTS RESERVED" *
* *
*-------------------------------------------------------------------------*/
#include <string.h>
// #include "sputl.h"
#include "spclidg.h"
/*--------------------- local defs ----------------------------------------*/
#define _ST_IDLE (0)
#define _ST_SEIZURE (1)
#define _ST_MARKS (2)
#define _ST_MSG (3)
#define _ST_DONE (4)
/*--------------------- public vars ---------------------------------------*/
// declared in sputla.s55 / .s54
extern S16 SP_asSinTab[];
const SPCLIDG_tCfg SPCLIDG_DefaultCfg = {
300,
180,
0,
1220
};
/*--------------------- local vars ----------------------------------------*/
/*--------------------- local functions -----------------------------------*/
/*-------------------------------------------------------------------------*/
static U16 _get_byte
/*-------------------------------------------------------------------------*/
(
SPCLIDG_tDb *pDb,
S16 sByteNo
)
{
S16 sIdx = sByteNo >> 1;
U16 uByte = pDb->auMsg[sIdx];
if (!(sByteNo & 1))
{
uByte >>= 8;
}
uByte &= 0x00ff;
return uByte;
}
// generate phase on 24 kHz
/*-------------------------------------------------------------------------*/
static void _get_phase24
/*-------------------------------------------------------------------------*/
(
SPCLIDG_tDb *pDb
)
{
S32 ac0 = pDb->sPhase;
ac0 += 3277; // 1200 Hz, 32768 * 1200 / (24000/2);
if(!pDb->sBit) // space
{
ac0 += 2731;// 1000 Hz more, to make 2200 Hz
}
// automatic phase wrap around
pDb->sPhase = (S16)ac0;
pDb->sSample++;
// if new bit
if (pDb->sSample >= 20) // (24000 / 1200 baud)
{
pDb->sSample = 0;
switch (pDb->sState)
{
case _ST_SEIZURE: // seizure 01010101
pDb->sBit ^= 1;
pDb->sBitNo ++;
if (pDb->sBitNo >= pDb->Cfg.sSeizureBits)
{
pDb->sState = _ST_MARKS;
pDb->sBit = 1;
pDb->sBitNo = 0;
}
break;
case _ST_MARKS: // marks 11111
pDb->sBitNo ++;
if (pDb->sBitNo >= pDb->Cfg.sMarkBits)
{
pDb->sState = _ST_MSG;
pDb->sBitNo = 0;
}
break;
case _ST_MSG: // message
if (pDb->sBitNo == 0)
{
if (pDb->sByteNo == 0)
{
pDb->sChar = _get_byte(pDb, 0);
// for call waiting 0x0a;
pDb->sCS = pDb->sChar;
}
else if (pDb->sByteNo < pDb->sBytes)
{
pDb->sChar = _get_byte(pDb, pDb->sByteNo);
pDb->sCS += pDb->sChar;
}
else // last check sum byte
{
pDb->sChar = 0x100 - (pDb->sCS & 0xff);
}
pDb->sByteNo++;
if (pDb->sByteNo > (pDb->sBytes + 1))
{
pDb->sState = _ST_DONE;
pDb->sBit = 1; // marks at the end are ok
}
else
{
pDb->sBit = 0; // start bit
}
}
else if (pDb->sBitNo < 9)
{
// lsb first
pDb->sBit = pDb->sChar & 1;
pDb->sChar >>= 1;
}
else // if (_Gen.iBitNo >= 9) // stop bit & marks between bytes
{
S16 sBitsInWord = pDb->Cfg.sInterwordMarkBits + 9;
pDb->sBit = 1;
// if this is the last CS byte, add at least 3 marks after it
// to ensure that the this byte is not lost
if (pDb->sByteNo == (pDb->sBytes + 1))
{
if (sBitsInWord < 12)
sBitsInWord = 12;
}
if (pDb->sBitNo >= sBitsInWord)
{
pDb->sBitNo = -1;
}
}
pDb->sBitNo++;
break;
default:
break;
} // end of switch
}
}
/*--------------------- public functions ---------------------------------*/
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
void sp_clidg_init
/*-------------------------------------------------------------------------*/
(
void *p_db
)
{
SPCLIDG_tDb *pDb = (SPCLIDG_tDb *)p_db;
memset (pDb, 0, sizeof (SPCLIDG_tDb));
pDb->Cfg = SPCLIDG_DefaultCfg;
}
/*-------------------------------------------------------------------------*/
void sp_clidg_cfg
/*-------------------------------------------------------------------------*/
(
void *p_db,
void *p_cfg
)
{
SPCLIDG_tDb *pDb = (SPCLIDG_tDb *)p_db;
SPCLIDG_tCfg *pCfg = (SPCLIDG_tCfg *)p_cfg;
pDb->Cfg = *pCfg;
}
/*-------------------------------------------------------------------------*/
void sp_clidg_start
/*-------------------------------------------------------------------------*/
(
void *p_db
)
{
SPCLIDG_tDb *pDb = (SPCLIDG_tDb *)p_db;
// include type, len
pDb->sBytes = _get_byte(pDb, 1) + 2;
pDb->sSample = 0;
pDb->sPhase = 0;
pDb->sBitNo = 0;
pDb->sByteNo = 0;
if (pDb->Cfg.sSeizureBits)
{
pDb->sState = _ST_SEIZURE;
pDb->sBit = 0; // first shall be 0 = space
}
else
{
pDb->sState = _ST_MARKS;
pDb->sBit = 1; // all marks
}
}
/*-------------------------------------------------------------------------*/
S16 sp_clidg
/*-------------------------------------------------------------------------*/
(
void *p_db,
S16 *psTo
)
{
SPCLIDG_tDb *pDb = (SPCLIDG_tDb *)p_db;
int k;
if (pDb->sState == _ST_IDLE)
return SPCLIDG_IDLE;
if (pDb->sState == _ST_DONE)
return SPCLIDG_DONE;
for (k = 0; k < SP_FR_SZ; k++)
{
_get_phase24(pDb);
_get_phase24(pDb);
_get_phase24(pDb);
psTo[k] = pDb->sPhase; // save phase into out
}
for (k = 0; k < SP_FR_SZ; k++)
{
S32 acc;
S16 sIdx = psTo[k];
sIdx >>= 8;
sIdx &= 0xff;
acc = SP_asSinTab[sIdx] * (S32) pDb->Cfg.sLevel;
acc += (1<<14);
psTo[k] = (S16)(acc >> 15);
}
return SPCLIDG_ACTIVE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -