#!/usr/bin/env python
#
# Copyright 2004 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio 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, or (at your option)
# any later version.
#
# GNU Radio 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 GNU Radio; see the file COPYING.  If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#

#At 05:59 PM 12/24/2004 +0100, you wrote:
#
#> I am trying to build an AM receiver with gnuradio.
#> Can anybody tell me how to do this (example)?
#
#
#Hi Martin - here's the script I use all the time. Customise for your setup and data
#source. Currently this is for 8e6 sampling rate with a 2048 offset - my ssrp returns
#in the range 0-4096 with 0 at 2048. It takes a freq (in hz) and volume argument (values
#from .0005 for very strong signals to .05 work).   The actual AM demodulation is the
#gr.complex_to_mag()  which is followed by a 0-dc restorer.

from gnuradio import gr
from gnuradio import audio
#from gnuradio import ssrp
from gnuradio import mc4020
import sys

def build_graph (freq,sfactor):
        sampling_freq = 35468950
        #sampling_freq = 50000000
        flags=mc4020.BTTV_EXTEND_RAW_LINES  |mc4020.BTTV_NOGAP  | mc4020.BTTV_DO_NOT_EMULATE_AC_COUPLING#| mc4020.BTTV_DEC3
        # |mc4020.BTTV_DO_NOT_EMULATE_AC_COUPLING
        if((flags & mc4020.BTTV_DEC3)==mc4020.BTTV_DEC3):
           sampling_freq=sampling_freq/3 #sampling_freq=11822983.0
        #sampling_freq=sampling_freq/4
        #audio_rate=32000
        audio_rate=8000
        cfir_decimation=int(sampling_freq/(8*audio_rate))*8 # = 368
        print(cfir_decimation)
        fg = gr.flow_graph ()

        #src0 = ssrp.source_f(0)
        #My own driver for my own hacked bttv card to have functionality similar to mc4020
        #this driver has an output multiple of 1380352
        src0 = mc4020.source (sampling_freq,flags, "/dev/video0");

#       src0 = gr.file_source (gr.sizeof_short, "am_band", 1)
#        adj_in = gr.add_const_ss(-2048)
        adj_in = gr.add_const_ss(-105)  #dummy adj_in does nothing (add 0 to the signal) but has a big effect on the minimal bandwith of the fir filter I can use
        #keep_one_in_n=gr.keep_one_in_n(gr.sizeof_short,4)
        # compute FIR filter taps
        channel_coeffs = \
                gr.firdes.low_pass (
                  1.0,                  # gain
                  sampling_freq,
                  10e3,                 # low pass cutoff
                  130000,                 # width of transition band  
                                             # 123663.52 gives ntaps=317, if not using adj_in audio stops after about a second
                                             # 123663.53 gives ntaps=315, if not using adj_in audio keeps working 
                                             # 2436.1 gives ntaps=16017,if using dummy adj_in gives no audio at all 
                                             # 2436.2 gives ntaps=16015,if using dummy adj_in audio keeps working 
                  gr.firdes.WIN_HAMMING )

        # input: short; output: complex
        chan_filter1 = \
                gr.freq_xlating_fir_filter_scf (
                  cfir_decimation,
                  channel_coeffs,
                  freq,
                  sampling_freq )

        am_demod = gr.complex_to_mag ()

        diff = gr.fir_filter_fff ( 1, [1, -1] )
        integ = gr.iir_filter_ffd ( [1, 0], [0, .999] )
        
        scale = gr.multiply_const_ff (sfactor)

        audio_lp_coeffs = gr.firdes.low_pass (
                1.0, 32000, 6e3, 600,
                gr.firdes.WIN_HAMMING )

        audio_lp = gr.fir_filter_fff ( 1, audio_lp_coeffs )

#       dst = gr.file_sink (gr.sizeof_float, "950_am_out")
        dst = audio.sink ( audio_rate )
        #avg = gr.fir_filter_scc ( 4, [complex(1,0), complex(1,0),complex(1,0),complex(1,0)] )
        fg.connect ( src0, adj_in )  #uncomment this line to use dummy adj_in
        #fg.connect ( adj_in,  keep_one_in_n) #uncomment this line to use dummy adj_in
        #fg.connect ( src0, chan_filter1  ) #comment this line to use dummy adj_in
        #fg.connect(avg,chan_filter1)
        fg.connect(adj_in,chan_filter1)
        fg.connect ( chan_filter1, am_demod )
        #fg.connect ( am_demod, dst )
        fg.connect ( am_demod, diff )
        fg.connect ( diff, integ )
        fg.connect ( integ, scale )
        fg.connect ( scale, audio_lp )
        fg.connect ( audio_lp, dst )

        return fg

def main (args):
        
        nargs = len (args)
        if nargs == 2:
                freq=float (args[0])
                sfactor=float (args[1])
        else:
                sys.stderr.write ('usage: am_demod.py freq scale\n')
                sys.exit (1)

        fg = build_graph(freq,sfactor)
        fg.start()
        raw_input ('Press Enter to quit')
        fg.stop()

if __name__ == '__main__':
        main (sys.argv[1:])


