root/experimental/components/Demodulator/src/DemodulatorDSP.cpp @ 3998

Revision 3998, 5.3 KB (checked in by jgaeddert, 6 years ago)

Adding more demod functions, writing test scripts

  • 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 Demodulator.
6
7OSSIE Demodulator is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12OSSIE Demodulator is distributed in the hope that it will be useful,
13but 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
18along with OSSIE Demodulator; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21****************************************************************************/
22
23
24#include <iostream>
25#include "DemodulatorDSP.h"
26#include <math.h>
27
28// Default constructor
29DemodulatorDSP::DemodulatorDSP()
30{
31    SetModulationScheme( MOD_BPSK );
32}
33
34// Destructor
35DemodulatorDSP::~DemodulatorDSP()
36{
37}
38
39// Set modulation scheme
40void DemodulatorDSP::SetModulationScheme( ModulationScheme _ms )
41{
42    switch ( _ms ) {
43    case MOD_BPSK:
44        Demodulate = &DemodulateBPSK;
45        bitsPerSymbol = 1;
46        differentialMode = false;
47        break;
48    case MOD_QPSK:
49        Demodulate = &DemodulateQPSK;
50        bitsPerSymbol = 2;
51        differentialMode = false;
52        break;
53    case MOD_8PSK:
54        Demodulate = &Demodulate8PSK;
55        bitsPerSymbol = 3;
56        differentialMode = false;
57        break;
58    case MOD_16QAM:
59        Demodulate = &Demodulate16QAM;
60        bitsPerSymbol = 4;
61        differentialMode = false;
62        break;
63    case MOD_4PAM:
64        Demodulate = &Demodulate4PAM;
65        bitsPerSymbol = 2;
66        differentialMode = false;
67        break;
68    case MOD_DBPSK:
69        state_i = 0;
70        state_q = 0;
71        Demodulate = &DemodulateBPSK;
72        bitsPerSymbol = 1;
73        differentialMode = true;
74        break;
75    case MOD_DQPSK:
76        state_i = 0;
77        state_q = 0;
78        Demodulate = &DemodulateQPSK;
79        bitsPerSymbol = 2;
80        differentialMode = true;
81        break;
82    case MOD_D8PSK:
83        state_i = 0;
84        state_q = 0;
85        Demodulate = &Demodulate8PSK;
86        bitsPerSymbol = 3;
87        differentialMode = true;
88        break;
89    default:
90        std::cerr << "ERROR: DemodulatorDSP::SetModulationScheme(): "
91                  << "unknown mod. scheme " << _ms << std::endl;
92        std::cerr << "  => Using BPSK instead" << std::endl;
93        SetModulationScheme( MOD_BPSK );
94        //throw 0;
95    }
96   
97    mod_scheme = _ms;
98}
99
100///
101void DemodulatorDSP::DemodulateSequence(
102        short * I_in,
103        short * Q_in,
104        unsigned int N_in,
105        char * bits_out)
106{
107    unsigned int i, j(0);
108
109    // If QAM or PAM correct for amplitude
110    if ( mod_scheme == MOD_16QAM || mod_scheme == MOD_4PAM ) {
111        ScaleSignalAmplitude(I_in, Q_in, N_in, TARGET_SIGNAL_ENERGY);
112    }
113
114    if ( differentialMode ) {
115        ///\todo implement differential PSK demodulation
116        std::cerr << "ERROR: DemodulatorDSP::DemodulateSequence(): "
117                  << "differential mode not yet supported!" << std::endl;
118        throw 0;
119    } else {
120        for (i=0; i<N_in; i++) {
121            Demodulate(I_in[i], Q_in[i], bits_out+j);
122            j += bitsPerSymbol;
123        }
124    }
125}
126
127
128//
129void DemodulatorDSP::ScaleSignalAmplitude(
130    short * I_in,
131    short * Q_in,
132    unsigned int N_in,
133    unsigned int targetEnergy)
134{
135    unsigned int i;
136    float energy(0.0f), scalingFactor;
137    for (i=0; i<N_in; i++) {
138        energy += float(I_in[i])*float(I_in[i]);
139        energy += float(Q_in[i])*float(Q_in[i]);
140    }
141    energy /= float(N_in);
142
143    scalingFactor = float(targetEnergy)/sqrtf(energy);
144
145    for (i=0; i<N_in; i++) {
146        I_in[i] = short( I_in[i]*scalingFactor );
147        Q_in[i] = short( Q_in[i]*scalingFactor );
148    }
149}
150
151
152//
153void DemodulateBPSK(
154    short & I_in,
155    short & Q_in,
156    char * bits_out)
157{
158    bits_out[0] = ( I_in > 0 ) ? BIT1 : BIT0;
159}
160
161//
162void DemodulateQPSK(
163    short & I_in,
164    short & Q_in,
165    char * bits_out)
166{
167    bits_out[0] = ( I_in > 0 ) ? BIT1 : BIT0;
168    bits_out[1] = ( Q_in > 0 ) ? BIT1 : BIT0;
169}
170
171//
172void Demodulate8PSK(
173    short & I_in,
174    short & Q_in,
175    char * bits_out)
176{
177    // rotate constellation counter-clockwise by 22.5 degrees
178    ///\todo Find more efficient way to rotate by 22.5 degrees
179    short I = short(  float(I_in*DEMOD_COS_22_5) - float(Q_in*DEMOD_SIN_22_5)  );
180    short Q = short(  float(I_in*DEMOD_SIN_22_5) + float(Q_in*DEMOD_COS_22_5)  );
181
182    bits_out[0] = ( I > 0 ) ? BIT0 : BIT1;
183    bits_out[1] = ( Q > 0 ) ? BIT0 : BIT1;
184    if ( ( Q>I && -I>Q ) || ( Q>-I && I>Q ) )
185        bits_out[2] = BIT0;
186    else
187        bits_out[2] = BIT1;
188}
189
190//
191void Demodulate16QAM(
192    short & I_in,
193    short & Q_in,
194    char * bits_out)
195{
196    std::cerr << "ERROR: Demodulate16QAM not yet supported!" << std::endl;
197    throw 0;
198}
199
200//
201void Demodulate4PAM(
202    short & I_in,
203    short & Q_in,
204    char * bits_out)
205{
206    if ( I_in > 0 ) {
207        bits_out[0] = BIT0;
208        bits_out[1] = ( I_in >  PAM4_THRESHOLD ) ? BIT0 : BIT1;
209    } else {
210        bits_out[0] = BIT1;
211        bits_out[1] = ( I_in < -PAM4_THRESHOLD ) ? BIT0 : BIT1;
212    }
213}
214
215
Note: See TracBrowser for help on using the browser.