root/SigProc/branches/SigProc-c/src/sigprocc.h @ 5709

Revision 5709, 12.3 KB (checked in by jgaeddert, 6 years ago)

adding scaling values for QAM and PAM modulation schemes

  • Property svn:eol-style set to native
Line 
1/****************************************************************************
2
3Copyright 2007 Virginia Polytechnic Institute and State University
4
5This file is part of the OSSIE Signal Processing C Library.
6
7OSSIE Signal Processing C Library is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 2 of the License,
10or (at your option) any later version.
11
12OSSIE Signal Processing C Library is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License along
18with OSSIE Signal Processing C Library; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21
22****************************************************************************/
23
24#ifndef __SIG_PROC_C_H__
25#define __SIG_PROC_C_H__
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <math.h>
31
32#ifdef __cplusplus
33extern "C"
34{
35#endif /* __cplusplus */
36
37#ifdef FPM
38#include "fixed.h"
39#endif
40
41#define PI      3.14159265358979f
42#define TWO_PI  6.28318530717959f
43
44//-----------------------------------------------------------------------------
45//
46// Design root raised-cosine filter
47//
48//-----------------------------------------------------------------------------
49void design_rrc_filter(
50  unsigned int k,      // samples per symbol
51  unsigned int m,      // delay
52  float beta,          // rolloff factor ( 0 < beta <= 1 )
53  float * h            // pointer to filter coefficients
54);
55
56//-----------------------------------------------------------------------------
57//
58// Design Gaussian filter
59//
60//-----------------------------------------------------------------------------
61void design_gaussian_filter(
62  unsigned int k,      // samples per symbol
63  unsigned int m,      // delay
64  float beta,          // rolloff factor ( 0 < beta <= 1 )
65  float * h            // pointer to filter coefficients
66);
67
68//-----------------------------------------------------------------------------
69//
70// Design low-pass butterworth filter
71//
72//-----------------------------------------------------------------------------
73void design_butter_lowpass_filter(
74  unsigned int order,   // filter order
75  float wc,             // cutoff frequency
76  float *b,             // feedback
77  float *a              // feedforward
78);
79
80//-----------------------------------------------------------------------------
81//
82// Circular buffer
83//
84//-----------------------------------------------------------------------------
85/** \brief Circlar buffer structure
86 *
87 * \section CB_basic_description Basic Description
88 * The circular buffer template class implementation minimizes memory copies
89 * by wrapping the array around to its beginning.  Elements can be added
90 * and removed by invoking the Push() and Pop() methods, respectively.
91 *
92 * \section CB_creating Creating Buffers
93 * There are three ways to create a buffer...
94 * \code
95 * // 1. generate an empty buffer
96 * CircularBuffer <short> v1(100);
97 *
98 * // 2. wrap an existing array
99 * short * x = new short[100];
100 * for (unsigned int i=0; i<100; i++)
101 *     x[i] = i;
102 * CircularBuffer <short> v2(x, 100);
103 *
104 * // 3. copy from another CircularBuffer
105 * CircularBuffer <short> v3(v2);
106 * \endcode
107 *
108 * \section CB_resizing_buffers Resizing Buffers
109 * CircularBuffer supports dynamic memory allocation as well; if an instance
110 * of CircularBuffer is created of a particular size and then later it is
111 * determined that the size is too small, invoking SetBufferSize() can be used
112 * to increase the length without loss of data.  However, decreasing the buffer
113 * size beyond the number of elements in the buffer truncates the data.
114 *
115 * \section CB_wrapping Wrapping
116 * When the buffer is full and another element is pushed, the new element
117 * overwrites the last element in the buffer without warning.  Status of the
118 * buffer can be checked with the GetBufferSize() and GetNumElements()
119 * methods.
120 *
121 */
122
123struct circular_buffer {
124    float * v;
125    unsigned int len;
126    unsigned int head_index;
127};
128
129typedef struct circular_buffer circular_buffer_t;
130
131/// Create circular buffer object, including memory allocation
132circular_buffer_t * circular_buffer_create(unsigned int buffer_lenth);
133
134/// Initialize circular buffer object
135void circular_buffer_initialize(circular_buffer_t * c, float * _v, unsigned int buffer_length);
136
137/// Push value into buffer
138void circular_buffer_push(circular_buffer_t * c, float x);
139
140/// Index value within buffer
141float circular_buffer_value(circular_buffer_t * c, unsigned int i);
142
143/// Linearize a circular buffer object
144void circular_buffer_linearize(circular_buffer_t * c);
145
146/// Get pointer to linearized buffer object
147float * circular_buffer_getpointer(circular_buffer_t * c);
148
149/// Print buffer values to screen
150void circular_buffer_print(circular_buffer_t * c);
151
152/// Destroy circular buffer object, free memory
153void circular_buffer_destroy(circular_buffer_t * c);
154
155//-----------------------------------------------------------------------------
156//
157// P/N Sequence
158//
159//-----------------------------------------------------------------------------
160
161
162//-----------------------------------------------------------------------------
163//
164// Automatic Gain Control class
165//
166//-----------------------------------------------------------------------------
167/** \brief Automatic gain control signal processor
168 *
169 * \cite  R. G. Lyons, Understanding Digital Signal Processing, 2nd ed. New Jersey:
170 * Prentice Hall, 2004.
171 */
172
173//-----------------------------------------------------------------------------
174//
175// FIR polyphase filter bank
176//
177//-----------------------------------------------------------------------------
178/** \brief Finite impulse response (FIR) polyphase filter bank
179 *
180 * This class implementes a finite impulse response (FIR) polyphase filter
181 * bank useful for decimators that need to interpolate samples in digital
182 * receivers.
183 *
184 * The filter bank can automatically calculate filter coefficients for
185 * prototypes commonly used in communications systems. Currently, such
186 * supported filter prototypes are
187 *   - root raised-cosine
188 *
189 * Filter prototypes that will eventually be supported are
190 *   - raised-cosine
191 *   - gaussian
192 *   - triangular
193 *   - hamming
194 *
195 * The user can also load filter coefficients that have been calculated
196 * externally.
197 *
198 * \image latex polyphase_rcos_filter_k2_N4.eps "Example filter bank (1)"
199 * \image html polyphase_rcos_filter_k2_N4.png  "Example filter bank (1)"
200 *
201 * \image latex polyphase_rcos_filter_k4_N2.eps "Example filter bank (2)"
202 * \image html polyphase_rcos_filter_k4_N2.png  "Example filter bank (2)"
203 *
204 * \cite M. Rice and fred harris, "Polyphase Filterbanks for Symbol Timing
205 * Synchronization in Sampled Data Receivers," in MILCOMM Proceedings, vol.
206 * 2, October 2002, pp. 982--986.
207 *
208 */
209
210struct polyphase_filterbank {
211    float * H;
212    unsigned int Npfb;
213    unsigned int h_len;
214    circular_buffer_t * v;
215};
216
217typedef struct polyphase_filterbank polyphase_filterbank_t;
218
219//
220void polyphase_filterbank_initialize();
221
222//-----------------------------------------------------------------------------
223//
224// Dot product definitions
225//
226//-----------------------------------------------------------------------------
227float dot_product(float *x, float *y, unsigned int N);
228//short dot_product(short *x, short *y, unsigned int N);
229//short dot_product(float *x, short *y, unsigned int N);
230//float dot_product(float *x, short *y, unsigned int N);
231
232//-----------------------------------------------------------------------------
233//
234// Misellany
235//
236//-----------------------------------------------------------------------------
237
238/// Uniform random number generator, (0,1]
239float randf();
240
241/// Gaussian random number generator, N(0,1)
242void randnf(float * i, float * q);
243
244//-----------------------------------------------------------------------------
245//
246// Trigonometric functions
247//
248//-----------------------------------------------------------------------------
249float arctan(float x, float y);
250
251
252//-----------------------------------------------------------------------------
253//
254// Byte packing functions
255//
256//-----------------------------------------------------------------------------
257void pack_bytes(
258    char * input,
259    unsigned int input_length,
260    char * output,
261    unsigned int output_length,
262    unsigned int *num_written);
263
264void unpack_bytes(
265    char * input,
266    unsigned int input_length,
267    char * output,
268    unsigned int output_length,
269    unsigned int *num_written);
270
271void repack_bytes(
272    char * input,
273    unsigned int input_sym_size,
274    unsigned int input_length,
275    char * output,
276    unsigned int output_sym_size,
277    unsigned int output_length,
278    unsigned int *num_written);
279
280
281//-----------------------------------------------------------------------------
282//
283// Modulation functions
284//
285//-----------------------------------------------------------------------------
286
287///
288enum modulation_scheme {
289        UNKNOWN,                                // Unknown modulation scheme
290        BPSK,   QPSK,   PSK8,   PSK16,          // Phase shift keying
291        DBPSK,  DQPSK,  DPSK8,  DPSK16,         // Differential PSK
292        PAM4,   PAM8,   PAM16,  PAM32,          // Pulse amplitude modulation
293        BFSK,   FSK4,   FSK8,   FSK16,          // Frequency shift keying
294        QAM16,  QAM32,  QAM64,  QAM128, QAM256  // Quadrature amplitude modulation
295        };
296
297#define BPSK_ALPHA      1
298#define QPSK_ALPHA      1/sqrt(2)
299
300#define QAM16_ALPHA     1/sqrt(10)
301#define QAM32_ALPHA     1/sqrt(20)
302#define QAM64_ALPHA     1/sqrt(42)
303#define QAM128_ALPHA    1/sqrt(82)
304#define QAM256_ALPHA    1/sqrt(170)
305
306#define PAM4_ALPHA      1/sqrt(5)
307#define PAM8_ALPHA      1/sqrt(21)
308#define PAM16_ALPHA     1/sqrt(85)
309
310#define BPSK_LEVEL      10000   ///< BPSK amplitude (RMS=10000)
311#define QPSK_LEVEL      7071    ///< QPSK amplitude (RMS=10000)
312#define PSK8_LEVEL_1    7071    ///< Low 8-PSK amplitude (RMS=10000)
313#define PSK8_LEVEL_2    10000   ///< High 8-PSK amplitude (RMS=10000)
314#define QAM16_LEVEL_1   3162    ///< Low 16-QAM amplitude (RMS=10000)
315#define QAM16_LEVEL_2   9487    ///< High 16-QAM amplitude (RMS=10000)
316#define PAM4_LEVEL_1    4472    ///< Low 4-PAM amplitude (RMS=10000)
317#define PAM4_LEVEL_2    13416   ///< High 4-PAM amplitude (RMS=10000)
318
319/// modulate_s a symbol into an I/Q pair for binary phase shift keying
320///
321/// \image latex ConstellationBPSK.eps "BPSK constellation"
322/// \image html ConstellationBPSK.png "BPSK constellation"
323void modulate_bpsk(short symbol_in, short *I_out, short *Q_out);
324
325/// modulate_s a symbol into an I/Q pair for quadrature phase shift keying
326///
327/// \image latex ConstellationQPSK.eps "QPSK constellation"
328/// \image html ConstellationQPSK.png "QPSK constellation"
329void modulate_qpsk(short symbol_in, short *I_out, short *Q_out);
330
331/// modulate_s a symbol into an I/Q pair for 8-ary phase shift keying
332///
333/// \image latex Constellation8PSK.eps "8-PSK constellation"
334/// \image html Constellation8PSK.png "8-PSK constellation"
335void modulate_8psk(short symbol_in, short *I_out, short *Q_out);
336
337/// modulate_s a symbol into an I/Q pair for 16-point quadrature
338/// amplitude modulation
339///
340/// \image latex Constellation16QAM.eps "16-QAM constellation"
341/// \image html Constellation16QAM.png "16-QAM constellation"
342void modulate_16qam(short symbol_in, short *I_out, short *Q_out);
343
344/// modulate_s a symbol into an I/Q pair for 4-ary pulse amplitude
345/// modulation
346///
347/// \image latex Constellation4PAM.eps "4-PAM constellation"
348/// \image html Constellation4PAM.png "4-PAM constellation"
349void modulate_4pam(short symbol_in, short *I_out, short *Q_out);
350
351
352#define DEMOD_COS_22_5 0.923879532511287
353#define DEMOD_SIN_22_5 0.382683432365090
354
355#define QAM16_THRESHOLD 6324    ///< 16-QAM threshold for RMS=10000 signal
356#define PAM4_THRESHOLD  8944    ///< 4-PAM threshold for RMS=10000 signal
357
358///
359void demodulate_bpsk(short I_in, short Q_in, short *symbol_out);
360
361///
362void demodulate_qpsk(short I_in, short Q_in, short *symbol_out);
363
364///
365void demodulate_8psk(short I_in, short Q_in, short *symbol_out);
366
367///
368void demodulate_16qam(short I_in, short Q_in, short *symbol_out);
369
370///
371void demodulate_4pam(short I_in, short Q_in, short *symbol_out);
372
373#ifdef __cplusplus
374}  /* extern "C" */
375#endif /* __cplusplus */
376
377#endif /* __SIG_PROC_H__ */
378
379
Note: See TracBrowser for help on using the browser.