'''Convert an arbitrary frequency in the FM broadcast band to the frequency of the nearest radio station frequency. Mike Markowski, mike.ab3ap@gmail.com Feb 2021 ''' import numpy as np from gnuradio import gr import pmt class snapBlock(gr.basic_block): def __init__(self): gr.basic_block.__init__( self, name="Snap to Station", in_sig=None, out_sig=None) # User input that is only somewhere near a station frequency. self.message_port_register_in(pmt.intern('raw_Hz_in')) self.set_msg_handler(pmt.intern('raw_Hz_in'), self.stationSnap) # Output in Hz and MHz that is exactly a station frequency. self.message_port_register_out(pmt.intern('snapped_Hz_out')) self.message_port_register_out(pmt.intern('snapped_MHz_out')) def stationSnap(self, msg): '''Accept a pmt pair with user selected frequency information and adjust it to the nearest broadcast FM frequency. Inputs: msg (dictionary) : assumed to contain only: (freq . ) Outputs: freq_Hz_out (pmt.dict) : (freq . snappedFreq) where snappedFreq is input frequency in Hz moved to nearest broadcast frequency. freq_MHz_out (pmt.dict) : (freq . snappedFreq) where snappedFreq is input frequency in MHz moved to nearest broadcast frequency. ''' # Disassemble pmt pair. cmd = pmt.car(msg) freq = pmt.cdr(msg) freqRaw_MHz = pmt.to_python(freq) / 1e6 # Easier to work in MHz. # Snap user-clicked freq to nearest FM station. spacing = 0.2 # N. American broadcast FM spacing in MHz. nearest = 0.1 # Round to nearest odd tenth of MHz. freq_MHz = nearest + round((freqRaw_MHz - nearest)/spacing) * spacing freq_Hz = freq_MHz * 1e6 # Generate output message, (freq . freq_Hz). pair = pmt.cons(cmd, pmt.to_pmt(freq_Hz)) self.message_port_pub(pmt.intern('snapped_Hz_out'), pair) # Generate output message, (freq . freq_MHz). pair = pmt.cons(cmd, pmt.to_pmt(freq_MHz)) self.message_port_pub(pmt.intern('snapped_MHz_out'), pair)