'''
Version: May 3, 2010

@author: Michel Barbeau
'''
# Import the GNU Radio module
from gnuradio import gr, optfir
from gnuradio import audio
from gnuradio import usrp2
from gnuradio import blks2

# Define the top block of the radio
class wfm_rx_block (gr.top_block):
    def __init__(self):
        gr.top_block.__init__(self)
              
	# Frequency (in Hz)
        # self._usrp_freq = 90.6 * 1e6 # Radio Canada Ottawa
        self._usrp_freq = 93.3 * 1e6 # CBC Radio One Ottawa
        self._audio_rate = int(44.1e3)
	# Network interface
        self.interface = "eth0"
        self.mac_addr = ""
        self.audio_output = ""
        
        # Get output of ADC 
        self.anADC = usrp2.source_32fc(self.interface, self.mac_addr)
        
        # calculate decimation values to get USRP BW at 320 kHz
        self.calculate_usrp_bw(320e3)

        # Set USRP decimation rate
        self.set_decim(self._usrp_decim)
        
        # Compute the coefficients of a low pass FIR filter
        coefficients = optfir.low_pass (
            1,                  # Filter gain in the passband (linear)
            self._usrp_rate,    # Sampling rate (in sps)
            80e3,               # End of pass band (in Hz)
            115e3,              # Start of stop band (in Hz)
            0.1,                # Pass band ripple in dB (should be small, < 1)
            60)                 # Stop band attenuation in dB (should be large, >= 60)

        # Create FIR filter
        aFIR = gr.fir_filter_ccf (self._chanfilt_decim, coefficients)

        # Create FM demodulator
        aDemodulator = blks2.wfm_rcv (self._demod_rate, self._audio_decim)
        
        # sound card as final sink
        aSoundCard = audio.sink (self._audio_rate, self.audio_output)
        
	# set the gain
        g = self.anADC.gain_range()
        self.anADC.set_gain(g[1])

	# set the frequency
        self.anADC.set_center_freq(self._usrp_freq)

        # Build the graph
        self.connect (self.anADC, aFIR, aDemodulator, aSoundCard)
             
    def calculate_usrp_bw(self, bw):
        """
        Calculate the different decimation rates that make the USRP BW equal to the
        input bandwidth parameter 'bw' and the audio bandwidth equal to the system-
        wide bandwidth 'self._audio_rate'
        """
        print "Calculate USRP BW!"
        
        adc_rate = self.anADC.adc_rate()
        print "ADC Rate is:", adc_rate, "samples/sec"
            
        d_usrp = int(adc_rate/bw)
        bw_real = adc_rate / float(d_usrp)

        d_chan = 1
        demod_rate = bw_real / d_chan

        d_audio = int(bw_real / self._audio_rate)
        audio_rate = demod_rate / d_audio

        self._usrp_decim  = d_usrp
        self._chanfilt_decim = d_chan
        self._audio_decim = d_audio
        self._demod_rate = demod_rate
        self._usrp_rate = bw_real
        
    def set_decim(self, decim):
        self._usrp_decim = int(decim)
        self.anADC.set_decim(self._usrp_decim)
        
if __name__ == '__main__':
    try:
        wfm_rx_block().run()
    except KeyboardInterrupt:
        pass

