📄 delay.cpp
字号:
// Delay.cpp: implementation of the CDelay class.
// ( also performs Hilbert Real to complex I/Q 3KHz filtering )
//////////////////////////////////////////////////////////////////////
// Copyright 2000. Moe Wheatley AE4JY <ae4jy@mindspring.com>
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "pathsim.h"
#include "Delay.h"
#include "FilterTables.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define MAXDELAY (50*8) // 50mSecs max delay
#define BLOCKSIZE 2048
#define BUFSIZE (BLOCKSIZE+MAXDELAY)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDelay::CDelay()
{
m_pDelayLine = new _complex[BUFSIZE];
m_pQue = new _complex[HILBPFIR_LENGTH];
m_Inptr = 0;
m_T1ptr = 0;
m_T2ptr = 0;
}
CDelay::~CDelay()
{
if(m_pDelayLine)
delete m_pDelayLine;
if(m_pQue)
delete m_pQue;
}
//////////////////////////////////////////////////////////////////////
// Set delay times
//////////////////////////////////////////////////////////////////////
void CDelay::SetDelays( double t1, double t2) //delays in msecs
{
for( INT i = 0; i<HILBPFIR_LENGTH; i++)
{
m_pQue[i].x = 0.0;
m_pQue[i].y = 0.0;
}
for( i = 0; i<BUFSIZE; i++)
{
m_pDelayLine[i].x = 0.0;
m_pDelayLine[i].y = 0.0;
}
m_Inptr = BUFSIZE-1;
m_FirState = HILBPFIR_LENGTH-1;
m_T1ptr = BUFSIZE - (INT)(8.0*t1) - 1;
m_T2ptr = BUFSIZE - (INT)(8.0*t2) - 1;
}
//////////////////////////////////////////////////////////////////////
// Uses pointers to create variable delays
//////////////////////////////////////////////////////////////////////
void CDelay::CreateDelays( _complex* inbuf, _complex* t1buf, _complex* t2buf )
{
INT i;
for(i=0; i<BLOCKSIZE; i++)
{
m_pDelayLine[m_Inptr++] = inbuf[i]; // copy new data from inbuf into delay buffer
if( m_Inptr >= BUFSIZE )
m_Inptr = 0;
t1buf[i] = m_pDelayLine[m_T1ptr++];
if( m_T1ptr >= BUFSIZE )
m_T1ptr = 0;
t2buf[i] = m_pDelayLine[m_T2ptr++];
if( m_T2ptr >= BUFSIZE )
m_T2ptr = 0;
}
}
//////////////////////////////////////////////////////////////////////
// Hilbert 3KHz BP filters. Real input and complex I/Q output
// This FIR bandwidth limits the real input as well as creates a
// complex I/Q output signal for the rest of the processing chain.
//////////////////////////////////////////////////////////////////////
void CDelay::CalcBPFilter(double* pIn, _complex* pOut)
{
_complex acc;
const double* IKptr;
const double* QKptr;
_complex* Firptr;
INT j;
for(INT i=0; i<BLOCKSIZE; i++)
{
m_pQue[m_FirState].x = pIn[i]; //place real values in circular Queue
m_pQue[m_FirState].y = pIn[i];
Firptr = m_pQue;
IKptr = IHilbertBPFirCoef+HILBPFIR_LENGTH-m_FirState;
QKptr = QHilbertBPFirCoef+HILBPFIR_LENGTH-m_FirState; //
acc.x = 0.0;
acc.y = 0.0;
for(j=0; j< HILBPFIR_LENGTH;j++)
{
acc.x += ( (Firptr->x)*(*IKptr++) );
acc.y += ( (Firptr++->y)*(*QKptr++) );
}
pOut[i].x = acc.x;
pOut[i].y = acc.y;
if( --m_FirState < 0)
m_FirState = HILBPFIR_LENGTH-1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -