示例#1
0
文件: top.py 项目: ptanguy/shinysdr
    def __init__(self, devices={}, audio_config=None, features=_stub_features):
        if len(devices) <= 0:
            raise ValueError('Must have at least one RF device')
        
        gr.top_block.__init__(self, "SDR top block")
        self.__running = False  # duplicate of GR state we can't reach, see __start_or_stop
        self.__has_a_useful_receiver = False

        # Configuration
        # TODO: device refactoring: Remove vestigial 'accessories'
        self._sources = {k: d for k, d in devices.iteritems() if d.can_receive()}
        self._accessories = accessories = {k: d for k, d in devices.iteritems() if not d.can_receive()}
        self.source_name = self._sources.keys()[0]  # arbitrary valid initial value
        self.__rx_device_type = Enum({k: v.get_name() or k for (k, v) in self._sources.iteritems()})
        
        # Audio early setup
        self.__audio_manager = AudioManager(  # must be before contexts
            graph=self,
            audio_config=audio_config,
            stereo=features['stereo'])

        # Blocks etc.
        # TODO: device refactoring: remove 'source' concept (which is currently a device)
        # TODO: remove legacy no-underscore names, maybe get rid of self.source
        self.source = None
        self.__monitor_rx_driver = None
        self.monitor = MonitorSink(
            signal_type=SignalType(sample_rate=10000, kind='IQ'),  # dummy value will be updated in _do_connect
            context=Context(self))
        self.monitor.get_interested_cell().subscribe(self.__start_or_stop_later)
        self.__clip_probe = MaxProbe()
        
        # Receiver blocks (multiple, eventually)
        self._receivers = {}
        self._receiver_valid = {}
        
        # collections
        # TODO: No longer necessary to have these non-underscore names
        self.sources = CollectionState(self._sources)
        self.receivers = ReceiverCollection(self._receivers, self)
        self.accessories = CollectionState(accessories)
        self.__telemetry_store = TelemetryStore()
        
        # Flags, other state
        self.__needs_reconnect = [u'initialization']
        self.__in_reconnect = False
        self.receiver_key_counter = 0
        self.receiver_default_state = {}
        self.__cpu_calculator = LazyRateCalculator(lambda: time.clock())
        
        # Initialization
        
        def hookup_vfo_callback(k, d):  # function so as to not close over loop variable
            d.get_vfo_cell().subscribe(lambda: self.__device_vfo_callback(k))
        
        for k, d in devices.iteritems():
            hookup_vfo_callback(k, d)
        
        self._do_connect()
示例#2
0
    def __init__(self, mode='MODE-S', input_rate=0, context=None):
        assert input_rate > 0
        gr.hier_block2.__init__(
            self,
            type(self).__name__, gr.io_signature(1, 1,
                                                 gr.sizeof_gr_complex * 1),
            gr.io_signature(0, 0, 0))

        demod_rate = 2000000
        transition_width = 500000

        hex_msg_queue = gr.msg_queue(100)

        self.__band_filter = MultistageChannelFilter(
            input_rate=input_rate,
            output_rate=demod_rate,
            cutoff_freq=demod_rate / 2,
            transition_width=transition_width)  # TODO optimize filter band
        self.__demod = air_modes.rx_path(
            rate=demod_rate,
            threshold=7.0,  # default used in air-modes code but not exposed
            queue=hex_msg_queue,
            use_pmf=False,
            use_dcblock=True)
        self.connect(self, self.__band_filter, self.__demod)

        self.__messages_seen = 0
        self.__message_rate_calc = LazyRateCalculator(
            lambda: self.__messages_seen, min_interval=2)

        # Parsing
        # TODO: These bits are mimicking gr-air-modes toplevel code. Figure out if we can have less glue.
        # Note: gr pubsub is synchronous -- subscribers are called on the publisher's thread
        parser_output = gr.pubsub.pubsub()
        parser = air_modes.make_parser(parser_output)
        cpr_decoder = air_modes.cpr_decoder(
            my_location=None)  # TODO: get position info from device
        air_modes.output_print(cpr_decoder, parser_output)

        def msq_runner_callback(msg):  # called on msgq_runner's thread
            # pylint: disable=broad-except
            try:
                reactor.callFromThread(parser, msg.to_string())
            except Exception:
                print(traceback.format_exc())

        self.__msgq_runner = gru.msgq_runner(hex_msg_queue,
                                             msq_runner_callback)

        def parsed_callback(msg):
            timestamp = time.time()
            self.__messages_seen += 1
            context.output_message(
                ModeSMessageWrapper(msg, cpr_decoder, timestamp))

        for i in six.moves.range(0, 2**5):
            parser_output.subscribe('type%i_dl' % i, parsed_callback)