def __init__(self, options, queue):
		gr.top_block.__init__(self)

		if options.filename is not None:
			self.fs = gr.file_source(gr.sizeof_gr_complex, options.filename)
			self.rate = options.rate

		else:
			self.u = uhd.usrp_source(options.addr,
									 io_type=uhd.io_type.COMPLEX_FLOAT32,
									 num_channels=1)

			if options.subdev is not None:
				self.u.set_subdev_spec(options.subdev, 0)
				
			self.u.set_samp_rate(options.rate)
			self.rate = self.u.get_samp_rate()

			# Set the antenna
			if(options.antenna):
				self.u.set_antenna(options.antenna, 0)
			
			self.centerfreq = options.centerfreq
			print "Tuning to: %fMHz" % (self.centerfreq - options.error)
			if not(self.tune(options.centerfreq - options.error)):
				print "Failed to set initial frequency"

			if options.gain is None: #set to halfway
				g = self.u.get_gain_range()
				options.gain = (g.start()+g.stop()) / 2.0

			print "Setting gain to %i" % options.gain
			self.u.set_gain(options.gain)

			self.u.set_bandwidth(options.bandwidth)

		print "Samples per second is %i" % self.rate

		self._syms_per_sec = 3600;


		options.samples_per_second = self.rate
		options.syms_per_sec = self._syms_per_sec
		options.gain_mu = 0.01
		options.mu=0.5
		options.omega_relative_limit = 0.3
		options.syms_per_sec = self._syms_per_sec
		options.offset = options.centerfreq - options.freq
		print "Control channel offset: %f" % options.offset

		self.demod = fsk_demod(options)
		self.start_correlator = gr.correlate_access_code_tag_bb("10101100",
		                                                        0,
		                                                        "smartnet_preamble") #should mark start of packet
		self.smartnet_deinterleave = smartnet.deinterleave()
		self.smartnet_crc = smartnet.crc(queue)

		if options.filename is None:
			self.connect(self.u, self.demod)
		else:
			self.connect(self.fs, self.demod)

		self.connect(self.demod, self.start_correlator, self.smartnet_deinterleave, self.smartnet_crc)

		#hook up the audio patch
		if options.audio:
			self.audiorate = 48000
			self.audiotaps = gr.firdes.low_pass(1, self.rate, 8000, 2000, gr.firdes.WIN_HANN)
			self.prefilter_decim = int(self.rate / self.audiorate) #might have to use a rational resampler for audio
			print "Prefilter decimation: %i" % self.prefilter_decim
			self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(self.prefilter_decim, #decimation
									      self.audiotaps, #taps
									      0, #freq offset
									      self.rate) #sampling rate

			#on a trunked network where you know you will have good signal, a carrier power squelch works well. real FM receviers use a noise squelch, where
			#the received audio is high-passed above the cutoff and then fed to a reverse squelch. If the power is then BELOW a threshold, open the squelch.
			self.squelch = gr.pwr_squelch_cc(options.squelch, #squelch point
											   alpha = 0.1, #wat
											   ramp = 10, #wat
											   gate = False)

			self.audiodemod = blks2.fm_demod_cf(self.rate/self.prefilter_decim, #rate
							    1, #audio decimation
							    4000, #deviation
							    3000, #audio passband
							    4000, #audio stopband
							    1, #gain
							    75e-6) #deemphasis constant

			#the filtering removes FSK data woobling from the subaudible channel (might be able to combine w/lpf above)
			self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300, 50, gr.firdes.WIN_HANN)
			self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)
			self.audiogain = gr.multiply_const_ff(options.volume)
			self.audiosink = audio.sink (self.audiorate, "")
#			self.audiosink = gr.wavfile_sink("test.wav", 1, self.audiorate, 8)

			self.mute()

			if options.filename is None:
				self.connect(self.u, self.audio_prefilter)
			else:
				self.connect(self.fs, self.audio_prefilter)

#			self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audioresamp, self.audiosink)
			self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audiosink)
Exemple #2
0
    def __init__(self, talkgroup, options):
        gr.hier_block2.__init__(
            self,
            "fsk_demod",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature(0, 0, gr.sizeof_char))  # Output signature

        #print "Starting log_receiver init()"

        self.audiorate = options.audiorate
        self.rate = options.rate
        self.talkgroup = talkgroup
        self.directory = options.directory

        if options.squelch is None:
            options.squelch = 28

        if options.volume is None:
            options.volume = 3.0

        self.audiotaps = gr.firdes.low_pass(1, self.rate, 8000, 2000,
                                            gr.firdes.WIN_HANN)

        self.prefilter_decim = int(self.rate / self.audiorate)

        #the audio prefilter is a channel selection filter.
        self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(
            self.prefilter_decim,  #decimation
            self.audiotaps,  #taps
            0,  #freq offset
            int(self.rate))  #sampling rate

        #on a trunked network where you know you will have good signal, a carrier power squelch works well. real FM receviers use a noise squelch, where
        #the received audio is high-passed above the cutoff and then fed to a reverse squelch. If the power is then BELOW a threshold, open the squelch.
        self.squelch = gr.pwr_squelch_cc(
            options.squelch,  #squelch point
            alpha=0.1,  #wat
            ramp=10,  #wat
            gate=True
        )  #gated so that the audio recording doesn't contain blank spaces between transmissions

        self.audiodemod = blks2.fm_demod_cf(
            self.rate / self.prefilter_decim,  #rate
            1,  #audio decimation
            4000,  #deviation
            3000,  #audio passband
            4000,  #audio stopband
            options.volume,  #gain
            75e-6)  #deemphasis constant

        #the filtering removes FSK data woobling from the subaudible channel
        self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300, 50,
                                                 gr.firdes.WIN_HANN)

        self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)

        #self.audiogain = gr.multiply_const_ff(options.volume)

        #here we generate a random filename in the form /tmp/[random].wav, and then use it for the wavstamp block. this avoids collisions later on. remember to clean up these files when deallocating.

        self.tmpfilename = "/tmp/%s.wav" % (
            "".join([
                random.choice(string.letters + string.digits) for x in range(8)
            ])
        )  #if this looks glaringly different, it's because i totally cribbed it from a blog.

        self.valve = grc_blks2.valve(gr.sizeof_float, bool(1))

        #self.prefiltervalve = grc_blks2.valve(gr.sizeof_gr_complex, bool(1))

        #open the logfile for appending
        self.timestampfilename = "%s/%i.txt" % (self.directory, self.talkgroup)
        self.timestampfile = open(self.timestampfilename, 'a')

        self.filename = "%s/%i.wav" % (self.directory, self.talkgroup)
        self.audiosink = smartnet.wavsink(
            self.filename, 1, self.audiorate,
            8)  #this version allows appending to existing files.

        #		self.connect(self, self.audio_prefilter, self.squelch, self.audiodemod, self.valve, self.audiofilt, self.audiosink)
        self.connect(self, self.audio_prefilter, self.audiodemod, self.valve,
                     self.audiofilt, self.audiosink)

        self.timestamp = 0.0

        #print "Finishing logging receiver init()."

        self.mute()  #start off muted.
Exemple #3
0
    def __init__(self, talkgroup, options):
        gr.hier_block2.__init__(
            self,
            "fsk_demod",
            gr.io_signature(1, 1, gr.sizeof_gr_complex),  # Input signature
            gr.io_signature(0, 0, gr.sizeof_char))  # Output signature

        print "Starting log_receiver init()"
        self.samp_rate = samp_rate = int(options.rate)
        self.samp_per_sym = samp_per_sym = 10
        self.decim = decim = 20
        self.xlate_bandwidth = xlate_bandwidth = 24260.0
        self.xlate_offset = xlate_offset = 0
        self.channel_rate = channel_rate = op25.SYMBOL_RATE * samp_per_sym
        self.audio_mul = audio_mul = 1
        self.pre_channel_rate = pre_channel_rate = int(samp_rate / decim)

        self.squelch = squelch = -55
        self.auto_tune_offset = auto_tune_offset = 0
        self.audiorate = 44100  #options.audiorate
        self.rate = options.rate
        self.talkgroup = talkgroup
        self.directory = options.directory

        if options.squelch is None:
            options.squelch = 28

        if options.volume is None:
            options.volume = 3.0

        ##################################################
        # Blocks
        ##################################################
        print "Setting up Blocks"

        self.audiotaps = gr.firdes.low_pass(1, samp_rate, 8000, 2000,
                                            gr.firdes.WIN_HANN)

        self.prefilter_decim = int(self.rate / self.audiorate)

        #the audio prefilter is a channel selection filter.
        self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(
            self.prefilter_decim,  #decimation
            self.audiotaps,  #taps
            0,  #freq offset
            int(samp_rate))  #sampling rate

        self.audiodemod = blks2.fm_demod_cf(
            self.rate / self.prefilter_decim,  #rate
            1,  #audio decimation
            4000,  #deviation
            3000,  #audio passband
            4000,  #audio stopband
            options.volume,  #gain
            75e-6)  #deemphasis constant

        #the filtering removes FSK data woobling from the subaudible channel
        self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300, 50,
                                                 gr.firdes.WIN_HANN)

        self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)

        self.gr_quadrature_demod_cf_0 = analog.quadrature_demod_cf(
            1.6)  #(channel_rate/(2.0 * math.pi * op25.SYMBOL_DEVIATION)))
        self.gr_freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(
            decim, (firdes.low_pass(1, samp_rate, xlate_bandwidth / 2, 2000)),
            0, samp_rate)
        self.gr_fir_filter_xxx_0 = filter.fir_filter_fff(
            1, ((1.0 / samp_per_sym, ) * samp_per_sym))

        self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff(
            (10.**(audio_mul / 10.), ))
        self.blks2_rational_resampler_xxx_1 = blks2.rational_resampler_ccc(
            interpolation=channel_rate,
            decimation=pre_channel_rate,
            taps=None,
            fractional_bw=None,
        )
        self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_fff(
            interpolation=self.audiorate,
            decimation=8000,
            taps=None,
            fractional_bw=None,
        )

        #here we generate a random filename in the form /tmp/[random].wav, and then use it for the wavstamp block. this avoids collisions later on. remember to clean up these files when deallocating.

        self.tmpfilename = "/tmp/%s.wav" % (
            "".join([
                random.choice(string.letters + string.digits) for x in range(8)
            ])
        )  #if this looks glaringly different, it's because i totally cribbed it from a blog.

        self.valve = grc_blks2.valve(gr.sizeof_float, bool(1))
        self.dsd_block_ff_0 = dsd.block_ff(dsd.dsd_FRAME_AUTO_DETECT,
                                           dsd.dsd_MOD_AUTO_SELECT, 3, 2, True)

        #open the logfile for appending
        self.timestampfilename = "%s/%i.txt" % (self.directory, self.talkgroup)
        self.timestampfile = open(self.timestampfilename, 'a')

        self.filename = "%s/%i.wav" % (self.directory, self.talkgroup)
        self.audiosink = smartnet.wavsink(
            self.filename, 1, self.audiorate, 8
        )  #blocks.wavfile_sink(self.filename, 1, self.audiorate, 8) this version allows appending to existing files.

        self.audio_sink_0 = audio.sink(44100, "", True)

        self.timestamp = 0.0

        #print "Finishing logging receiver init()."

        self.mute()  #start off muted.
        print "Connecting blocks"

        ##################################################
        # Connections
        ##################################################

        self.connect(self.blks2_rational_resampler_xxx_0,
                     self.blocks_multiply_const_vxx_0)

        self.connect(self.gr_fir_filter_xxx_0, self.valve, self.dsd_block_ff_0)
        self.connect(self.dsd_block_ff_0, self.blks2_rational_resampler_xxx_0)

        ## Start
        self.connect(self, self.gr_freq_xlating_fir_filter_xxx_0,
                     self.blks2_rational_resampler_xxx_1,
                     self.gr_quadrature_demod_cf_0, self.gr_fir_filter_xxx_0)

        ## End
        # self.connect(self.blocks_multiply_const_vxx_0, self.audio_sink_0) # Plays the audio
        self.connect(self.blocks_multiply_const_vxx_0,
                     self.audiosink)  # Records the audio
    def __init__(self, options, queue):
        gr.top_block.__init__(self)

        if options.filename is not None:
            self.fs = gr.file_source(gr.sizeof_gr_complex, options.filename)
            self.rate = options.rate

        else:
            self.u = uhd.usrp_source(options.addr,
                                     io_type=uhd.io_type.COMPLEX_FLOAT32,
                                     num_channels=1)

            if options.subdev is not None:
                self.u.set_subdev_spec(options.subdev, 0)

            self.u.set_samp_rate(options.rate)
            self.rate = self.u.get_samp_rate()

            # Set the antenna
            if (options.antenna):
                self.u.set_antenna(options.antenna, 0)

            self.centerfreq = options.centerfreq
            print "Tuning to: %fMHz" % (self.centerfreq - options.error)
            if not (self.tune(options.centerfreq - options.error)):
                print "Failed to set initial frequency"

            if options.gain is None:  #set to halfway
                g = self.u.get_gain_range()
                options.gain = (g.start() + g.stop()) / 2.0

            print "Setting gain to %i" % options.gain
            self.u.set_gain(options.gain)

            self.u.set_bandwidth(options.bandwidth)

        print "Samples per second is %i" % self.rate

        self._syms_per_sec = 3600

        options.samples_per_second = self.rate
        options.syms_per_sec = self._syms_per_sec
        options.gain_mu = 0.01
        options.mu = 0.5
        options.omega_relative_limit = 0.3
        options.syms_per_sec = self._syms_per_sec
        options.offset = options.centerfreq - options.freq
        print "Control channel offset: %f" % options.offset

        self.demod = fsk_demod(options)
        self.start_correlator = gr.correlate_access_code_tag_bb(
            "10101100", 0, "smartnet_preamble")  #should mark start of packet
        self.smartnet_deinterleave = smartnet.deinterleave()
        self.smartnet_crc = smartnet.crc(queue)

        if options.filename is None:
            self.connect(self.u, self.demod)
        else:
            self.connect(self.fs, self.demod)

        self.connect(self.demod, self.start_correlator,
                     self.smartnet_deinterleave, self.smartnet_crc)

        #hook up the audio patch
        if options.audio:
            self.audiorate = 48000
            self.audiotaps = gr.firdes.low_pass(1, self.rate, 8000, 2000,
                                                gr.firdes.WIN_HANN)
            self.prefilter_decim = int(
                self.rate / self.audiorate
            )  #might have to use a rational resampler for audio
            print "Prefilter decimation: %i" % self.prefilter_decim
            self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(
                self.prefilter_decim,  #decimation
                self.audiotaps,  #taps
                0,  #freq offset
                self.rate)  #sampling rate

            #on a trunked network where you know you will have good signal, a carrier power squelch works well. real FM receviers use a noise squelch, where
            #the received audio is high-passed above the cutoff and then fed to a reverse squelch. If the power is then BELOW a threshold, open the squelch.
            self.squelch = gr.pwr_squelch_cc(
                options.squelch,  #squelch point
                alpha=0.1,  #wat
                ramp=10,  #wat
                gate=False)

            self.audiodemod = blks2.fm_demod_cf(
                self.rate / self.prefilter_decim,  #rate
                1,  #audio decimation
                4000,  #deviation
                3000,  #audio passband
                4000,  #audio stopband
                1,  #gain
                75e-6)  #deemphasis constant

            #the filtering removes FSK data woobling from the subaudible channel (might be able to combine w/lpf above)
            self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300,
                                                     50, gr.firdes.WIN_HANN)
            self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)
            self.audiogain = gr.multiply_const_ff(options.volume)
            self.audiosink = audio.sink(self.audiorate, "")
            #			self.audiosink = gr.wavfile_sink("test.wav", 1, self.audiorate, 8)

            self.mute()

            if options.filename is None:
                self.connect(self.u, self.audio_prefilter)
            else:
                self.connect(self.fs, self.audio_prefilter)

#			self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audioresamp, self.audiosink)
            self.connect(self.audio_prefilter, self.squelch, self.audiodemod,
                         self.audiofilt, self.audiogain, self.audiosink)
    def __init__(self, options, queue):
        gr.top_block.__init__(self)

        if options.filename is not None:
            self.fs = gr.file_source(gr.sizeof_gr_complex, options.filename)
            self.rate = options.rate

        else:
            #self.u = uhd.usrp_source(options.addr,
            #						 io_type=uhd.io_type.COMPLEX_FLOAT32,
            #						 num_channels=1)

            self.rtl = osmosdr.source_c(args="nchan=" + str(1) + " " + "")
            self.rtl.set_sample_rate(options.rate)
            self.rate = options.rate  #self.rtl.get_samp_rate()
            self.rtl.set_center_freq(options.centerfreq, 0)
            #self.rtl.set_freq_corr(options.ppm, 0)

            self.centerfreq = options.centerfreq
            print "Tuning to: %fMHz" % (self.centerfreq - options.error)
            if not (self.tune(options.centerfreq - options.error)):
                print "Failed to set initial frequency"

            if options.gain is None:
                options.gain = 10
            if options.bbgain is None:
                options.bbgain = 25
            if options.ifgain is None:
                options.ifgain = 25

            print "Setting RF gain to %i" % options.gain
            print "Setting BB gain to %i" % options.bbgain
            print "Setting IF gain to %i" % options.ifgain

            self.rtl.set_gain(options.gain, 0)
            self.rtl.set_if_gain(options.ifgain, 0)
            self.rtl.set_bb_gain(options.bbgain, 0)
            #self.rtl.set_gain_mode(1,0)

        print "Samples per second is %i" % self.rate

        self._syms_per_sec = 3600

        options.samples_per_second = self.rate
        options.syms_per_sec = self._syms_per_sec
        options.gain_mu = 0.01
        options.mu = 0.5
        options.omega_relative_limit = 0.3
        options.syms_per_sec = self._syms_per_sec
        options.offset = options.centerfreq - options.freq
        print "Control channel offset: %f" % options.offset

        self.offset = gr.sig_source_c(self.rate, gr.GR_SIN_WAVE,
                                      options.offset, 1.0, 0.0)

        # for some reason using the xlating filter to do the offset makes thing barf with the HackRF, Multiply CC seems to work

        options.offset = 0

        self.mixer = gr.multiply_cc()

        self.demod = fsk_demod(options)
        self.start_correlator = gr.correlate_access_code_tag_bb(
            "10101100", 0, "smartnet_preamble")  #should mark start of packet
        self.smartnet_deinterleave = smartnet.deinterleave()
        self.smartnet_crc = smartnet.crc(queue)

        #rerate = float(self.rate / float(first_decim)) / float(7200)
        #print "resampling factor: %f\n" % rerate

        #if rerate.is_integer():
        #    print "using pfb decimator\n"
        #    self.resamp = blks2.pfb_decimator_ccf(int(rerate))
        #else:
        #    print "using pfb resampler\n"
        #    self.resamp = blks2.pfb_arb_resampler_ccf(1 / rerate)

        if options.filename is None:
            #self.connect(self.u, self.demod)
            self.connect(self.rtl, (self.mixer, 0))
            self.connect(self.offset, (self.mixer, 1))
            self.connect(self.mixer, self.demod)
            #    self.connect(self.rtl, self.demod)
        else:
            self.connect(self.fs, self.demod)

        self.connect(self.demod, self.start_correlator,
                     self.smartnet_deinterleave, self.smartnet_crc)

        #hook up the audio patch
        if options.audio:
            self.audiorate = 48000
            self.audiotaps = gr.firdes.low_pass(1, self.rate, 8000, 2000,
                                                gr.firdes.WIN_HANN)
            self.prefilter_decim = int(
                self.rate / self.audiorate
            )  #might have to use a rational resampler for audio
            print "Prefilter decimation: %i" % self.prefilter_decim
            self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(
                self.prefilter_decim,  #decimation
                self.audiotaps,  #taps
                0,  #freq offset
                self.rate)  #sampling rate

            #on a trunked network where you know you will have good signal, a carrier power squelch works well. real FM receviers use a noise squelch, where
            #the received audio is high-passed above the cutoff and then fed to a reverse squelch. If the power is then BELOW a threshold, open the squelch.
            #self.squelch = gr.pwr_squelch_cc(options.squelch, #squelch point
            #								   alpha = 0.1, #wat
            #								   ramp = 10, #wat
            #								   gate = False)

            self.audiodemod = blks2.fm_demod_cf(
                self.rate / self.prefilter_decim,  #rate
                1,  #audio decimation
                4000,  #deviation
                3000,  #audio passband
                4000,  #audio stopband
                1,  #gain
                75e-6)  #deemphasis constant

            #the filtering removes FSK data woobling from the subaudible channel (might be able to combine w/lpf above)
            self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300,
                                                     50, gr.firdes.WIN_HANN)
            self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)
            self.audiogain = gr.multiply_const_ff(options.volume)
            self.audiosink = audio.sink(self.audiorate, "")
            #			self.audiosink = gr.wavfile_sink("test.wav", 1, self.audiorate, 8)

            #self.mute()

            if options.filename is None:
                #self.connect(self.u, self.audio_prefilter)
                self.connect(self.rtl, self.audio_prefilter)
            else:
                self.connect(self.fs, self.audio_prefilter)

#			self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audioresamp, self.audiosink)
#	real		self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audiosink)
            self.connect(self.audio_prefilter, self.audiodemod, self.audiofilt,
                         self.audiogain, self.audiosink)
	def __init__(self, options, queue):
		gr.top_block.__init__(self)

		if options.filename is not None:
			self.fs = gr.file_source(gr.sizeof_gr_complex, options.filename)
			self.rate = options.rate

		else:
			#self.u = uhd.usrp_source(options.addr,
			#						 io_type=uhd.io_type.COMPLEX_FLOAT32,
			#						 num_channels=1)

                    
                    self.rtl = osmosdr.source_c( args="nchan=" + str(1) + " " + ""  )
                    self.rtl.set_sample_rate(options.rate)
                    self.rate = options.rate #self.rtl.get_samp_rate()
                    self.rtl.set_center_freq(options.centerfreq, 0)
                    #self.rtl.set_freq_corr(options.ppm, 0)
                    
		
                    self.centerfreq = options.centerfreq
                    print "Tuning to: %fMHz" % (self.centerfreq - options.error)
                    if not(self.tune(options.centerfreq - options.error)):
			print "Failed to set initial frequency"

                    if options.gain is None: 
			options.gain = 10
                    if options.bbgain is None: 
			options.bbgain = 25
                    if options.ifgain is None: 
			options.ifgain = 25


                    print "Setting RF gain to %i" % options.gain
                    print "Setting BB gain to %i" % options.bbgain
                    print "Setting IF gain to %i" % options.ifgain

                    self.rtl.set_gain(options.gain, 0) 
                    self.rtl.set_if_gain(options.ifgain,0)
                    self.rtl.set_bb_gain(options.bbgain,0)
                    #self.rtl.set_gain_mode(1,0)

		print "Samples per second is %i" % self.rate

		self._syms_per_sec = 3600;


		options.samples_per_second = self.rate
		options.syms_per_sec = self._syms_per_sec
		options.gain_mu = 0.01
		options.mu=0.5
		options.omega_relative_limit = 0.3
		options.syms_per_sec = self._syms_per_sec
		options.offset = options.centerfreq - options.freq
		print "Control channel offset: %f" % options.offset

                self.offset = gr.sig_source_c(self.rate, gr.GR_SIN_WAVE,
                                              options.offset, 1.0, 0.0)
		
		# for some reason using the xlating filter to do the offset makes thing barf with the HackRF, Multiply CC seems to work

		options.offset = 0

                self.mixer = gr.multiply_cc()

		self.demod = fsk_demod(options)
		self.start_correlator = gr.correlate_access_code_tag_bb("10101100",
		                                                        0,
		                                                        "smartnet_preamble") #should mark start of packet
		self.smartnet_deinterleave = smartnet.deinterleave()
		self.smartnet_crc = smartnet.crc(queue)

                #rerate = float(self.rate / float(first_decim)) / float(7200)
                #print "resampling factor: %f\n" % rerate
                
                #if rerate.is_integer():
                #    print "using pfb decimator\n"
                #    self.resamp = blks2.pfb_decimator_ccf(int(rerate))
                #else:
                #    print "using pfb resampler\n"
                #    self.resamp = blks2.pfb_arb_resampler_ccf(1 / rerate)

		if options.filename is None:
			#self.connect(self.u, self.demod)
                    self.connect(self.rtl, (self.mixer, 0))
                    self.connect(self.offset, (self.mixer, 1))                    
                    self.connect(self.mixer, self.demod)
                    #    self.connect(self.rtl, self.demod)
		else:
			self.connect(self.fs, self.demod)

		self.connect(self.demod, self.start_correlator, self.smartnet_deinterleave, self.smartnet_crc)

		#hook up the audio patch
		if options.audio:
			self.audiorate = 48000
			self.audiotaps = gr.firdes.low_pass(1, self.rate, 8000, 2000, gr.firdes.WIN_HANN)
			self.prefilter_decim = int(self.rate / self.audiorate) #might have to use a rational resampler for audio
			print "Prefilter decimation: %i" % self.prefilter_decim
			self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(self.prefilter_decim, #decimation
									      self.audiotaps, #taps
									      0, #freq offset
									      self.rate) #sampling rate

			#on a trunked network where you know you will have good signal, a carrier power squelch works well. real FM receviers use a noise squelch, where
			#the received audio is high-passed above the cutoff and then fed to a reverse squelch. If the power is then BELOW a threshold, open the squelch.
			#self.squelch = gr.pwr_squelch_cc(options.squelch, #squelch point
			#								   alpha = 0.1, #wat
			#								   ramp = 10, #wat
			#								   gate = False)

			self.audiodemod = blks2.fm_demod_cf(self.rate/self.prefilter_decim, #rate
							    1, #audio decimation
							    4000, #deviation
							    3000, #audio passband
							    4000, #audio stopband
							    1, #gain
							    75e-6) #deemphasis constant

			#the filtering removes FSK data woobling from the subaudible channel (might be able to combine w/lpf above)
			self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300, 50, gr.firdes.WIN_HANN)
			self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)
			self.audiogain = gr.multiply_const_ff(options.volume)
			self.audiosink = audio.sink (self.audiorate, "")
#			self.audiosink = gr.wavfile_sink("test.wav", 1, self.audiorate, 8)

			#self.mute()

			if options.filename is None:
				#self.connect(self.u, self.audio_prefilter)
                                self.connect(self.rtl, self.audio_prefilter)
			else:
				self.connect(self.fs, self.audio_prefilter)

#			self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audioresamp, self.audiosink)
#	real		self.connect(self.audio_prefilter, self.squelch, self.audiodemod, self.audiofilt, self.audiogain, self.audiosink)
			self.connect(self.audio_prefilter, self.audiodemod, self.audiofilt, self.audiogain, self.audiosink)
	def __init__(self, talkgroup, options):
		gr.hier_block2.__init__(self, "fsk_demod",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
                                gr.io_signature(0, 0, gr.sizeof_char)) # Output signature

		#print "Starting log_receiver init()"

		self.audiorate = options.audiorate
		self.rate = options.rate
		self.talkgroup = talkgroup
		self.directory = options.directory

		if options.squelch is None:
			options.squelch = 28

		if options.volume is None:
			options.volume = 3.0

		self.audiotaps = gr.firdes.low_pass(1, self.rate, 8000, 2000, gr.firdes.WIN_HANN)

		self.prefilter_decim = int(self.rate / self.audiorate)

		#the audio prefilter is a channel selection filter.
		self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(self.prefilter_decim, #decimation
								      self.audiotaps, #taps
								      0, #freq offset
								      int(self.rate)) #sampling rate

		#on a trunked network where you know you will have good signal, a carrier power squelch works well. real FM receviers use a noise squelch, where
		#the received audio is high-passed above the cutoff and then fed to a reverse squelch. If the power is then BELOW a threshold, open the squelch.
		self.squelch = gr.pwr_squelch_cc(options.squelch, #squelch point
										   alpha = 0.1, #wat
										   ramp = 10, #wat
										   gate = True) #gated so that the audio recording doesn't contain blank spaces between transmissions

		self.audiodemod = blks2.fm_demod_cf(self.rate/self.prefilter_decim, #rate
						    1, #audio decimation
						    4000, #deviation
						    3000, #audio passband
						    4000, #audio stopband
						    options.volume, #gain
						    75e-6) #deemphasis constant

		#the filtering removes FSK data woobling from the subaudible channel
		self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300, 50, gr.firdes.WIN_HANN)

		self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)
		
		#self.audiogain = gr.multiply_const_ff(options.volume)

		#here we generate a random filename in the form /tmp/[random].wav, and then use it for the wavstamp block. this avoids collisions later on. remember to clean up these files when deallocating.

		self.tmpfilename = "/tmp/%s.wav" % ("".join([random.choice(string.letters+string.digits) for x in range(8)])) #if this looks glaringly different, it's because i totally cribbed it from a blog.

		self.valve = grc_blks2.valve(gr.sizeof_float, bool(1))

		#self.prefiltervalve = grc_blks2.valve(gr.sizeof_gr_complex, bool(1))

		#open the logfile for appending
		self.timestampfilename = "%s/%i.txt" % (self.directory, self.talkgroup)
		self.timestampfile = open(self.timestampfilename, 'a');

		self.filename = "%s/%i.wav" % (self.directory, self.talkgroup)
		self.audiosink = smartnet.wavsink(self.filename, 1, self.audiorate, 8) #this version allows appending to existing files.

#		self.connect(self, self.audio_prefilter, self.squelch, self.audiodemod, self.valve, self.audiofilt, self.audiosink)
		self.connect(self, self.audio_prefilter, self.audiodemod, self.valve, self.audiofilt, self.audiosink)

		self.timestamp = 0.0

		#print "Finishing logging receiver init()."

		self.mute() #start off muted.
	def __init__(self, talkgroup, options):
		gr.hier_block2.__init__(self, "fsk_demod",
                                gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
                                gr.io_signature(0, 0, gr.sizeof_char)) # Output signature

		print "Starting log_receiver init()"
		self.samp_rate = samp_rate = int(options.rate)
		self.samp_per_sym = samp_per_sym = 10
		self.decim = decim = 20
		self.xlate_bandwidth = xlate_bandwidth = 24260.0
		self.xlate_offset = xlate_offset = 0
		self.channel_rate = channel_rate = op25.SYMBOL_RATE*samp_per_sym
		self.audio_mul = audio_mul = 1
		self.pre_channel_rate = pre_channel_rate = int(samp_rate/decim)

		self.squelch = squelch = -55	
		self.auto_tune_offset = auto_tune_offset = 0	
		self.audiorate = 44100 #options.audiorate
		self.rate = options.rate
		self.talkgroup = talkgroup
		self.directory = options.directory

		if options.squelch is None:
			options.squelch = 28

		if options.volume is None:
			options.volume = 3.0


		##################################################
		# Blocks
		##################################################
		print "Setting up Blocks"

		self.audiotaps = gr.firdes.low_pass(1, samp_rate, 8000, 2000, gr.firdes.WIN_HANN)

		self.prefilter_decim = int(self.rate / self.audiorate)

		#the audio prefilter is a channel selection filter.
		self.audio_prefilter = gr.freq_xlating_fir_filter_ccf(self.prefilter_decim, #decimation
								      self.audiotaps, #taps
								      0, #freq offset
								      int(samp_rate)) #sampling rate

		self.audiodemod = blks2.fm_demod_cf(self.rate/self.prefilter_decim, #rate
						    1, #audio decimation
						    4000, #deviation
						    3000, #audio passband
						    4000, #audio stopband
						    options.volume, #gain
						    75e-6) #deemphasis constant

		#the filtering removes FSK data woobling from the subaudible channel
		self.audiofilttaps = gr.firdes.high_pass(1, self.audiorate, 300, 50, gr.firdes.WIN_HANN)

		self.audiofilt = gr.fir_filter_fff(1, self.audiofilttaps)

		self.gr_quadrature_demod_cf_0 = analog.quadrature_demod_cf(1.6) #(channel_rate/(2.0 * math.pi * op25.SYMBOL_DEVIATION)))
		self.gr_freq_xlating_fir_filter_xxx_0 = filter.freq_xlating_fir_filter_ccc(decim, 
										       (firdes.low_pass(1, samp_rate, xlate_bandwidth/2, 2000)),
										       0, 
										       samp_rate)
		self.gr_fir_filter_xxx_0 = filter.fir_filter_fff(1, ((1.0/samp_per_sym,)*samp_per_sym))
		
		self.blocks_multiply_const_vxx_0 = blocks.multiply_const_vff((10.**(audio_mul/10.), ))
		self.blks2_rational_resampler_xxx_1 = blks2.rational_resampler_ccc(
			interpolation=channel_rate,
			decimation=pre_channel_rate,
			taps=None,
			fractional_bw=None,
		)
		self.blks2_rational_resampler_xxx_0 = blks2.rational_resampler_fff(
			interpolation=self.audiorate,
			decimation=8000,
			taps=None,
			fractional_bw=None,
		)
			

		#here we generate a random filename in the form /tmp/[random].wav, and then use it for the wavstamp block. this avoids collisions later on. remember to clean up these files when deallocating.

		self.tmpfilename = "/tmp/%s.wav" % ("".join([random.choice(string.letters+string.digits) for x in range(8)])) #if this looks glaringly different, it's because i totally cribbed it from a blog.

		self.valve = grc_blks2.valve(gr.sizeof_float, bool(1))
		self.dsd_block_ff_0 = dsd.block_ff(dsd.dsd_FRAME_AUTO_DETECT,dsd.dsd_MOD_AUTO_SELECT,3,2,True)

		#open the logfile for appending
		self.timestampfilename = "%s/%i.txt" % (self.directory, self.talkgroup)
		self.timestampfile = open(self.timestampfilename, 'a');

		self.filename = "%s/%i.wav" % (self.directory, self.talkgroup)
		self.audiosink = smartnet.wavsink(self.filename, 1, self.audiorate, 8) #blocks.wavfile_sink(self.filename, 1, self.audiorate, 8) this version allows appending to existing files.

		self.audio_sink_0 = audio.sink(44100, "", True)


		self.timestamp = 0.0

		#print "Finishing logging receiver init()."

		self.mute() #start off muted.
		print "Connecting blocks"


	##################################################
	# Connections
		##################################################

		self.connect(self.blks2_rational_resampler_xxx_0, self.blocks_multiply_const_vxx_0)

		self.connect(self.gr_fir_filter_xxx_0 ,  self.valve, self.dsd_block_ff_0)
		self.connect(self.dsd_block_ff_0, self.blks2_rational_resampler_xxx_0)

		## Start
		self.connect(self, self.gr_freq_xlating_fir_filter_xxx_0, self.blks2_rational_resampler_xxx_1,  self.gr_quadrature_demod_cf_0, self.gr_fir_filter_xxx_0)

		## End
		# self.connect(self.blocks_multiply_const_vxx_0, self.audio_sink_0) # Plays the audio
		self.connect(self.blocks_multiply_const_vxx_0, self.audiosink) # Records the audio