#!/usr/bin/env python

import math

from gnuradio import gr
from gnuradio import audio
import sys
from gnuradio import mc4020
from gnuradio import v4ltuner
def high_speed_adc (fg, input_rate): #My own driver for my own hacked bttv card to have functionality similar to mc4020, ofcourse you can use your own high speed ADC source or a software generated signal
    return mc4020.source (input_rate,mc4020.BTTV_EXTEND_RAW_LINES  | mc4020.BTTV_DEC3 |mc4020.BTTV_NOGAP, "/dev/video0");

# return a gr.flow_graph
#
def build_chan_filter(freq,input_rate,cfir_decimation):
   # compute FIR filter taps for channel selection
    channel_coeffs = \
      gr.firdes.low_pass (
        1.0,          # gain
        input_rate,   # sampling rate
        100e3, #250e3,        low pass cutoff freq
        1e5,#800e3, #8*100e3,       width of trans. band
        gr.firdes.WIN_HAMMING)

    # input: short; output: complex
    chan_filter1 = \
      gr.freq_xlating_fir_filter_scf (
        cfir_decimation,
        channel_coeffs,
        freq,        # 1st station freq
        input_rate)
    return chan_filter1

def build_graph (src,freq1, input_rate,cfir_decimation,audio_decimation,chan_filter1):

    quad_rate = input_rate / cfir_decimation
    audio_rate =  quad_rate / audio_decimation
   
    (head1, tail1) = \
      build_pipeline (fg, quad_rate,
                      audio_decimation)
    
    # sound card as final sink
    audio_sink = audio.sink (int (audio_rate))
   
    # now wire it all together
    fg.connect (src, chan_filter1)
    fg.connect (chan_filter1, head1)
    fg.connect (tail1, (audio_sink, 0))
    
    return fg

def build_pipeline (fg, quad_rate, audio_decimation):
    '''Given a flow_graph, fg, construct a pipeline
    for demodulating a broadcast FM signal.  The
    input is the downconverteed complex baseband
    signal. The output is the demodulated audio.

    build_pipeline returns a two element tuple
    containing the input and output endpoints.
    '''
    # fm_demod_gain = 2200.0/32768.0
    audio_rate = quad_rate / audio_decimation
    # volume = 2.0

    # input: complex; output: float
    #fm_demod = \
    #  gr.quadrature_demod_cf (volume*fm_demod_gain)

    # HERE IS THE AM DEMODULATOR:
    am_demod = gr.abs_cf()

    # compute FIR filter taps for audio filter
    width_of_transition_band = audio_rate / 32
    audio_coeffs = \
      gr.firdes.low_pass (
        1.0,            # gain
        quad_rate,      # sampling rate
        audio_rate/2 - width_of_transition_band,
        width_of_transition_band,
        gr.firdes.WIN_HAMMING)

    # input: float; output: float
    audio_filter = \
      gr.fir_filter_fff (audio_decimation,
                         audio_coeffs)

    fg.connect (am_demod, audio_filter)
    return ((am_demod, 0), (audio_filter, 0))
    

if __name__ == '__main__':
    #f1 = float (sys.argv[1:][0]) 
    nargs = len (sys.argv[1:])
    #freq1 = IFfreq
    #tunerfreq = RFfreq
    if nargs == 1:
        freq1 = float (sys.argv[1:][0]) * 1e6
    elif nargs == 2:
        freq1 = float (sys.argv[1:][0]) * 1e6
        tunerfreq=float (sys.argv[1:][1]) * 1e6
    else:
        sys.stderr.write ('usage: am_receiver.py  IFfreq RFfreq\n')
        sys.stderr.write ('frequencies in MHz\n')
        sys.exit (1)
 
    #input_rate=int(50000000)  #50 Msps    # int(50000000.0 * 674*1024*50/35468950)
    #rate_fact = 1.0                   # (674.0*1024*50)/35468950
    input_rate=int(50000000* 674*1024*50/(35468950*3))
    rate_fact = (674.0*1024*50)/35468950.0
    #orig FM cfir_decimation = 125
    #orig FM audio_decimation = 5
    cfir_decimation = 128
    audio_decimation = 8

    fg = gr.flow_graph ()
    
    # use high speed ADC as input source
    src = high_speed_adc (fg, input_rate)

    chan_filter1=build_chan_filter(int(freq1*rate_fact),input_rate,cfir_decimation)
    fg2=build_graph(src,freq1*rate_fact,input_rate,cfir_decimation,audio_decimation,chan_filter1)
    actualtunerfreq=src.set_RF_freq(tunerfreq)
    freq1=freq1+(tunerfreq - actualtunerfreq)
    print(tunerfreq);
    print(actualtunerfreq);
    print(freq1);
    letter=""
    fg2.start ()        # fork thread(s) and return    
    while (letter!="x"):
        #print(freq1)
    	letter=raw_input ( 'Press x Enter to quit: ')
	if letter=="'": 
		tunerfreq+=100000
    	elif letter==";": 
		tunerfreq-=100000
        elif letter==">": 
		tunerfreq+=10000
	elif letter=="<": 
		tunerfreq-=10000
	elif letter==".": 
		tunerfreq+=1000
	elif letter==",": 
		tunerfreq-=1000
        else: 
		tunerfreq+=10000
	print(tunerfreq)
        print(src.set_RF_freq(tunerfreq))
	#chan_filter1.set_center_freq( int(freq1*rate_fact) ) 
    fg2.stop ()
    print "The end!"


