discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Discuss-gnuradio] Phase Locked Loop Code Part 1


From: Rick Parrish
Subject: [Discuss-gnuradio] Phase Locked Loop Code Part 1
Date: Sat, 08 Nov 2003 03:41:08 -0600
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030624


Ian;

Here's a PLL framework in C++. It's been available under the LGPL for a few years now. SymbolConsumer is abstract base class (or interface). You have to implement this yourself. I have examples for decoding a couple of trunked radio control channel protocols. Using the PhaseLockedLoop class below you describe your protocol's sample rate and symbol rate. Here a symbol is an octet, so you could accept a binary symbol set {0, 1}, 4 level FSK as {0, 1, 2, 3}, 16 QAM {0, 1, ... , 14, 15} or whatever. It was designed for use on narrow band FM signals where a single A/D converter was sufficient but could be adapted to I/Q style decoding.

Part 2 will show the impementation of the PhaseLockedLoop class. For each symbol it finds, it calls the SymbolConsumer's consume method. All the symbol consumer implementation need convern itself with is sequences of input symbols. Below is cut/paste of two separate source files SymbolConsumer.h and PhaseLockedLoop.h

-rick

#ifndef _DECODERS_H
#define _DECODERS_H

/* Abstract Symbol Consumer interface.    */
/* Copyright 2000 Rick Parrish            */

enum {eNull, eGrant, eContinuation, eRelease, eHealth, ePatch, eAffiliation, eControl, eCell, eSystem};

typedef void Logger(void *pContext, const char *msg);

class SymbolConsumer;

// nSysid - optional system id.
// nChannel - frequency code.
// nSource - radio ID - not available on continuations.
// nTarget - talk group or radio ID.
// nVerb - call, continuation, other.
// pszNotes - free text supplemental information.
typedef void Handler(void *pContext, long nSysid, short nVerb, short nChannel, long nSource, long nTarget, short nType, const char *strMsg, SymbolConsumer *pConsumer);

class SymbolConsumer
{
public:
virtual void setQuiet(bool bHush) = 0;
virtual void setHandler(Handler *pHandler) = 0;
virtual void setLogger(Logger *pLogger) = 0;
virtual void setContext(void *pContext) = 0;
virtual void consume(const char chSymbol) = 0;
virtual void destroy() = 0;
virtual void setOption(const char *strKey, int iValue) = 0;
virtual const char *getLabel() const = 0;
virtual const char *getCallType(unsigned char iType) const = 0;
};

typedef bool __stdcall ProtoEnumProtocols(const int iStep, char *strProtocol, unsigned short &uLen, unsigned short &uRate); typedef bool __stdcall ProtoGetInstance(const int iStep, SymbolConsumer* &pConsumer);

#endif

/* Copyright 2002 see the file "COPYING" for license. */

#ifndef _PhaseLockedLoop_H
#define _PhaseLockedLoop_H

#include "../Decoders/Decoders.h"

// converts samples to symbols
// converts symbol impulses to a stream of discrete symbols.
// note: when you see the word "symbol", think "bit"; most protocols use binary symbols. // in some cases a protocol will use symbols that encode two or more bits hence the generalization.

class PhaseLockedLoop
{
// private variables for automatic phase correction.
double _fPhase;
double _fDamp;
// time accumulator - measures time progress such as when it is time to sample the next symbol.
double _fAccumulate;
// time duration of a single symbol in seconds.
double _fBitTime;
// half of above time duration in seconds.
double _fBitHalfTime;
// target object to receive the stream of discrete symbols.
SymbolConsumer *_pConsumer;
// sampling rate for input device
unsigned long _dwSamplesPerSecond;
// option to invert incoming sample stream
bool _bInvert;
// symbol value last received.
char _chLastSymbol;
// duration of last impulse as # of samples.
long _nLastCount;
// symbol rate
unsigned long _iSymbolRate;

public:
CPhaseLockedLoop(const unsigned long dwSamplesPerSecond, const unsigned long dwSymbolsPerSecond, SymbolConsumer *pConsumer = NULL);
bool inputData(char, const long, const unsigned long);
bool setInvert(bool bInvert) { bool bWas = _bInvert; _bInvert = bInvert; return bWas; };
bool getInvert() const { return _bInvert; };
void setConsumer(SymbolConsumer *pConsumer);
void setSpeed(const unsigned long dwSymbolsPerSecond);
};

#endif







reply via email to

[Prev in Thread] Current Thread [Next in Thread]