#!/usr/bin/env python

import math
import time

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):
    return mc4020.source (input_rate,mc4020.BTTV_EXTEND_RAW_LINES  | mc4020.BTTV_NOGAP, "/dev/video0");
#mc4020.BTTV_EXTEND_RAW_LINES |mc4020.BTTV_DEC3 |mc4020.BTTV_DO_NOT_EMULATE_AC_COUPLING | mc4020.BTTV_DEC3
#
#    return gr.file_source (1, "/pub/tmp/pixels.raw", False)
#   return gr.file_source (gr.sizeof_short, "/pub/tmp/pixels.raw", False)
#return gr.file_source (gr.sizeof_short, "dummy.dat", False)
#
# 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
        25e3, #20e3,        low pass cutoff freq
        250e3,#200e3, #200#8*100e3,       width of trans. band
        gr.firdes.WIN_HAMMING)
    print(freq)
    # 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, freq2,input_rate,cfir_decimation,audio_decimation,chan_filter1):
    #input_rate = 20e6
    #input_rate = 8.5e6
    #input_rate = 5140800
    #input_rate = 16384000
    #cfir_decimation = 125
    #cfir_decimation = 62
    #audio_decimation = 4

    quad_rate = input_rate / cfir_decimation
    #audio_rate = quad_rate / audio_decimation
    audio_rate =  quad_rate / audio_decimation


    #sampling_freq = freq1*10
    #ampl = 0.1

    #fg = gr.flow_graph ()
    #src = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, freq1, ampl)
    
  
    
    (head1, tail1,squelch) = \
      build_pipeline (fg, quad_rate,
                      audio_decimation)
    
    # sound card as final sink
   # audio_sink = gr.audio_sink_oss (int (audio_rate)) # FIXME oss
    audio_sink = audio.sink (int (audio_rate))
   
    # now wire it all together
    #src_dec3 = gr.keep_one_in_n(gr.sizeof_short,4)
    #fg.connect(src,src_dec3)
    fg.connect (src, chan_filter1)
    fg.connect (chan_filter1, head1)
    fg.connect (tail1, (audio_sink, 0))

    # two stations at once?
    if freq2:
        # Extract the second station and connect
        # it to a second pipeline...

        # input: short; output: complex
        channel_coeffs = \
        gr.firdes.low_pass (
        1.0,          # gain
        input_rate,   # sampling rate
        250e3, #250e3,        low pass cutoff freq
        4*100e3, #8*100e3,       width of trans. band
        gr.firdes.WIN_HAMMING)
        chan_filter2 = \
          gr.freq_xlating_fir_filter_scf (
            cfir_decimation,
            channel_coeffs,
            freq2,        # 2nd station freq
            input_rate)

        (head2, tail2) = \
          build_pipeline (fg, quad_rate,
                          audio_decimation)

        fg.connect (src, chan_filter2)
        fg.connect (chan_filter2, head2)
        fg.connect (tail2, (audio_sink, 1))
    
    return fg,squelch

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
    # gr_squelch_cc (  double		sampling_freq,
    # float threshold,
    # float	avg_time_fast,
    # float	holdtime,
    # float	unmutetime,
    # bool autothreshold,
    # float avg_time_slow)
    squelch=gr.squelch_cc(quad_rate,
		1.18,#1.2,#1.1,#0.19,
		0.020,
		0.2,
		0.0,
		1,
		10.0)
    # input: complex; output: float
    fm_demod = \
      gr.quadrature_demod_cf (volume*fm_demod_gain)

    # 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(squelch,fm_demod)
    fg.connect (fm_demod, audio_filter)
    return ((squelch, 0), (audio_filter, 0),squelch)
    

def man (freq1,freq2):
    #nargs = len (args)
    #if nargs == 1:
    #    freq1 = float (args[0]) * 1e6
    #    freq2 = None
    #elif nargs == 2:
    #    freq1 = float (args[0]) * 1e6
    #    freq2 = float (args[1]) * 1e6
    #else:
    #    sys.stderr.write ('usage: fm_demod freq1 [freq2]\n')
    #    sys.exit (1)

    # connect to RF front end
    #rf_front_end = gr.microtune_4937_eval_board ()
    #rf_front_end = v4l_tuner ("/dev/video0")
    #if not rf_front_end.board_present_p ():
    #    raise IOError, 'RF front end not found'

    # set front end gain
    #rf_front_end.set_AGC (300)
    #IF_freq = rf_front_end.get_output_freq ()
    #IF_freq = 5.75e6
    IF_freq = 5.5e6
    if not freq2:      # one station

    #    rf_front_end.set_RF_freq (freq1)
        fg = build_graph (freq1, None)

    else:              # two stations

        if abs (freq1 - freq2) > 5.5e6:
            raise IOError, 'freqs too far apart'

        target_freq = (freq1 + freq2) / 2
        #actual_freq = rf_front_end.set_RF_freq (target_freq)
        actual_freq = target_freq
        
        fg = build_graph (IF_freq + freq1 - actual_freq,
                          IF_freq + freq2 - actual_freq)
    
    print "Just before run!"
    
    #fg.run ()          # FIXME
    #fg.start()
    #fg.start ()        # fork thread(s) and return
    #raw_input ('Press Enter to quit: ')
    #fg.stop ()
    return fg

if __name__ == '__main__':
    #f1 = float (sys.argv[1:][0]) 
    nargs = len (sys.argv[1:])
    tunerfreq= float(100000000.0)
    if nargs == 1:
        freq1 = float (sys.argv[1:][0]) * 1e6
        freq2 = None
    elif nargs == 2:
        freq1 = float (sys.argv[1:][0]) * 1e6
        #iffreq=freq1=11.0625
        tunerfreq=float (sys.argv[1:][1]) * 1e6
        freq2=None
        #freq2 = float (sys.argv[1:][1]) * 1e6
    else:
        sys.stderr.write ('usage: fm_demod freq1 [freq2]\n')
        sys.exit (1)
    #tuner=v4ltuner.v4l_tuner("/dev/video0")
    #fg2=man (freq1,freq2)
    #input_rate = 16384000 #1024*640*25
    #input_rate = 8164800 #567*288*50
    #input_rate = 16329600 #2268/2 *288*50
    #input_rate = 17718464 #= pllfreq/2
    #input_rate = int(35468950)#int( 674*1024*50)#35468950#640*1024*50 #674*1024*50 #35468950 #38900000.0 #0.9*35.46=31922055 #35468950 #32659200 2268*288*50
    input_rate=int(50000000* 674*1024*50/35468950)
    rate_fact = (674.0*1024*50)/35468950.0
    print(rate_fact)
    input_rate = int(input_rate) #/3
    #orig cfir_decimation = 125
    #orig audio_decimation = 5
    cfir_decimation = 640#80
    audio_decimation = 8#8#4

    fg = gr.flow_graph ()
    
    # use high speed ADC as input source
    # src = gr.high_speed_adc (input_rate)
    src = high_speed_adc (fg, input_rate)
    chan_filter1=build_chan_filter(int(freq1*rate_fact),input_rate,cfir_decimation)
    fg2,squelch=build_graph(src,freq1*rate_fact, freq2,input_rate,cfir_decimation,audio_decimation,chan_filter1)
    #fg2=build_graph(freq1,freq2,chan_filter1)
    print(tunerfreq);
    print(src.set_RF_freq(tunerfreq));
    chan_filter1.set_center_freq (freq1*rate_fact) 
    letter=""
    #Koninklijke Marechaussee Landelijk Kanaal 14 brigade Utrecht 	73.920
    #Politie Amersfoort District Eemland-Zuid	77.850
    #Politie Amersfoort District Eemland-Zuid	78.5375
    #Politie Amersfoort District Eemland-Zuid	86.250
    #Politie Amersfoort, Speciale acties	86.250
    #Politie Regio Amersfoort Meldkamer Utrecht	86.935000
    #Taxi Keistad Amersfoort / Taxi Eemland Soest 149.7875
    #Hoek-Tax Amersfoort                          151.6375
    #Stadswacht Amersfoort, kanaal 1 Amersfoort   152.0125
    #Meander Ziekenhuis Amersfoort kanaal 1       152.1125
    #Brandweer Amersfoort Portofoon (Wit)         153.7885
    #Brandweer Amersfoort Portofoon (Rood)        153.8375
    #Brandweer Amersfoort Portofoon (Geel)        153.9375
    #Bij een uitruk zit de bemanning van de TS (tankautospuit) en/of HV (hulpverleningswagen) op (Blauw)
    #                                             154.0125
    #Stadswacht Amersfoort, kanaal 2 Amersfoort   158.4100
    #Afotax Taxicentrale                          158.8300
    #Bestax Amersfoort                            158.9100
    #AVD 2                                        159.1900

    freqs_vhf_l=[86.937500,86.250,78.5375,77.850,86.9350]
    #freqs_vhf_l=[86.937500,86.250,86.9350]
    #freqs_vhf_l=[149.7875,151.6375,152.0125,152.1125,153.7885,153.8375,153.9375,154.0125,158.4100,158.8300,158.9100]
    #freqs_vhf_l=[455.8100,456.9300,456.9700,459.1100,466.5500,466.9250,466.9750,467.1125,468.5300,469.1900]
    #455.8900,455.9300,
    #freqs_vhf_l=[466.5500,466.9250,466.9750]

    #freqs_vhf_l=[107.9,107.9]
    fg2.start ()        # fork thread(s) and return    
    counter=int(0)
    tunerfreq=src.set_RF_freq(tunerfreq)#get actual tunerfreq
    while (letter!="x"):
        #print(freq1)
    	#letter=raw_input ( 'Press x Enter to quit: ')
        time.sleep(0.05)
        counter=counter+1
        if((counter+1)> len(freqs_vhf_l)):
           counter=0
        current_rf_freq=freqs_vhf_l[counter]
        current_if_freq=(freq1 +current_rf_freq*1e6 -tunerfreq)*rate_fact
        current_rf_freq_check=tunerfreq+(current_if_freq/rate_fact)-freq1
        chan_filter1.set_center_freq (current_if_freq)
        #while(squelch.d_hold):
        while(squelch.get_hold()):
           #print(tunerfreq)
           #print(current_rf_freq)
           print(current_rf_freq_check)
           print(current_if_freq)
           time.sleep(0.3)
	#chan_filter1.set_center_freq( int(freq1*rate_fact) ) 
    fg2.stop ()

    #fg2=man (freq1,freq2)
    #fg2.start ()   
    print "Just after main!"


