⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spclidg.c

📁 This R2.9 revision of the CLID detector provides the TYPE 1 (on-hook, between first and second ring,
💻 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 + -