Imported Upstream version 3.2.2
[debian/gnuradio] / gnuradio-core / src / lib / general / gr_fmdet_cf.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2008 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <gr_fmdet_cf.h>
29 #include <gr_io_signature.h>
30 #include <math.h>
31 #include <gr_math.h>
32
33 #define M_TWOPI (2*M_PI)
34
35 gr_fmdet_cf_sptr
36 gr_make_fmdet_cf (float samplerate, float freq_low, float freq_high, float scl)
37 {
38   return gr_fmdet_cf_sptr (new gr_fmdet_cf (samplerate, freq_low, freq_high, scl));
39 }
40
41 gr_fmdet_cf::gr_fmdet_cf (float samplerate, float freq_low, float freq_high, float scl)
42   : gr_sync_block ("fmdet_cf",
43                    gr_make_io_signature (1, 1, sizeof (gr_complex)),
44                    gr_make_io_signature (1, 1, sizeof (float))),
45     d_S1(0.1),d_S2(0.1),
46     d_S3(0.1),d_S4(0.1)
47 {
48   float delta;
49   d_freqhi = freq_high;
50   d_freqlo = freq_low;
51   delta = (d_freqhi - d_freqlo);
52   d_scl = scl;
53   d_bias = 0.5*scl*(d_freqhi+d_freqlo)/delta;
54 }
55
56 int
57 gr_fmdet_cf::work (int noutput_items,
58                    gr_vector_const_void_star &input_items,
59                    gr_vector_void_star &output_items)
60 {
61   const gr_complex *iptr = (gr_complex *) input_items[0];
62   float *optr = (float *) output_items[0];
63
64   int   size = noutput_items;
65
66   gr_complex Sdot,S0,S1=d_S1,S2=d_S2,S3=d_S3,S4=d_S4;
67
68   while (size-- > 0) {
69     S0=*iptr++;
70
71     Sdot = gr_complex(d_scl*
72                       (-S0.real() + 8.0*S1.real() - 8.0*S3.real() + S4.real()),
73                       d_scl*
74                       (-S0.imag() + 8.0*S1.imag() - 8.0*S3.imag() + S4.imag()));
75     d_freq = (S2.real()*Sdot.imag()-S2.imag()*Sdot.real())/
76       (S2.real()*S2.real()+S2.imag()*S2.imag());
77
78     S4=S3;
79     S3=S2;
80     S2=S1;
81     S1=S0;
82
83     
84     *optr++ = d_freq-d_bias;
85   }
86   d_S1=S1;
87   d_S2=S2;
88   d_S3=S3;
89   d_S4=S4;
90   return noutput_items;
91 }