Пример #1
0
    def __init__(self, mode, input_rate=0, context=None):
        assert input_rate > 0
        self.__input_rate = input_rate
        gr.hier_block2.__init__(
            self, 'RTTY demodulator',
            gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
            gr.io_signature(1, 1, gr.sizeof_float * 1))
        
        channel_filter = self.__make_channel_filter()

        self.__text = u''
        self.__char_queue = gr.msg_queue(limit=100)
        self.__char_sink = blocks.message_sink(gr.sizeof_char, self.__char_queue, True)

        self.connect(
            self,
            channel_filter,
            self.__make_demodulator(),
            self.__char_sink)
        
        self.connect(
            channel_filter,
            self.__make_audio_filter(),
            blocks.rotator_cc(rotator_inc(self.__demod_rate, 2000 + self.__spacing / 2)),
            blocks.complex_to_real(vlen=1),
            analog.agc2_ff(
                reference=dB(-10),
                attack_rate=8e-1,
                decay_rate=8e-1),
            self)
Пример #2
0
 def __init__(self, modulator, audio_rate, rf_rate, freq):
     modulator = IModulator(modulator)
     
     gr.hier_block2.__init__(
         self, 'SimulatedChannel',
         gr.io_signature(1, 1, gr.sizeof_float * 1),
         gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
     )
     
     self.__freq = freq
     self.__rf_rate = rf_rate
     self.__modulator = modulator
     
     modulator_input_type = modulator.get_input_type()
     if modulator_input_type.get_kind() == 'MONO':
         audio_resampler = make_resampler(audio_rate, modulator_input_type.get_sample_rate())
         self.connect(self, audio_resampler, modulator)
     elif modulator_input_type.get_kind() == 'NONE':
         self.connect(self, blocks.null_sink(gr.sizeof_float))
     else:
         raise Exception('don\'t know how to supply input of type %s' % modulator_input_type)
     
     rf_resampler = rational_resampler.rational_resampler_ccf(
         interpolation=int(rf_rate),
         decimation=int(modulator.get_output_type().get_sample_rate()))
     self.__rotator = blocks.rotator_cc(rotator_inc(rate=rf_rate, shift=freq))
     self.__mult = blocks.multiply_const_cc(dB(-10))
     self.connect(modulator, rf_resampler, self.__rotator, self.__mult, self)
Пример #3
0
    def __init__(self, mode, input_rate=0, context=None):
        assert input_rate > 0
        self.__input_rate = input_rate
        gr.hier_block2.__init__(
            self, type(self).__name__,
            gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
            gr.io_signature(1, 1, gr.sizeof_float * 1))
        
        channel_filter = self.__make_channel_filter()

        self.__text_cell = StringSinkCell(encoding='us-ascii')
        self.__text_sink = self.__text_cell.create_sink_internal()

        self.connect(
            self,
            channel_filter,
            self.__make_demodulator(),
            self.__text_sink)
        
        self.connect(
            channel_filter,
            self.__make_audio_filter(),
            blocks.rotator_cc(rotator_inc(self.__demod_rate, 2000 + self.__spacing / 2)),
            blocks.complex_to_real(vlen=1),
            analog.agc2_ff(
                reference=dB(-10),
                attack_rate=8e-1,
                decay_rate=8e-1),
            self)
Пример #4
0
 def __update_audio_gain(self):
     gain_lin = dB(self.audio_gain)
     if self.__audio_channels == 2:
         pan = self.audio_pan
         # TODO: Determine correct computation for panning. http://en.wikipedia.org/wiki/Pan_law seems relevant but was short on actual formulas. May depend on headphones vs speakers? This may be correct already for headphones -- it sounds nearly-flat to me.
         self.__audio_gain_blocks[0].set_k(gain_lin * (1 - pan))
         self.__audio_gain_blocks[1].set_k(gain_lin * (1 + pan))
     else:
         self.__audio_gain_blocks[0].set_k(gain_lin)
Пример #5
0
 def __update_audio_gain(self):
     gain_lin = dB(self.audio_gain)
     if self.__audio_channels == 2:
         pan = self.audio_pan
         # TODO: Instead of left-to-left and right-to-right, panning other than center should mix left and right content. (A "pan law" defines the proper mix.) This implies a matrix multiplication type operation.
         self.__audio_gain_block.set_k([
             gain_lin * (1 - pan),
             gain_lin * (1 + pan),
         ])
     else:
         self.__audio_gain_block.set_k([gain_lin])
Пример #6
0
    def __init__(self, mode, input_rate, context):
        channels = 2
        audio_rate = 10000
        
        gr.hier_block2.__init__(
            self, str('%s demodulator' % (mode,)),
            gr.io_signature(1, 1, gr.sizeof_gr_complex),
            gr.io_signature(1, 1, gr.sizeof_float * channels))

        self.__input_rate = input_rate
        self.__rec_freq_input = 0.0
        self.__signal_type = SignalType(kind='STEREO', sample_rate=audio_rate)

        # Using agc2 rather than feedforward AGC for efficiency, because this runs at the RF rate rather than the audio rate.
        agc_block = analog.agc2_cc(reference=dB(-8))
        agc_block.set_attack_rate(8e-3)
        agc_block.set_decay_rate(8e-3)
        agc_block.set_max_gain(dB(40))
        
        self.connect(
            self,
            agc_block)
        
        channel_joiner = blocks.streams_to_vector(gr.sizeof_float, channels)
        self.connect(channel_joiner, self)
        
        for channel in xrange(0, channels):
            self.connect(
                agc_block,
                grfilter.fir_filter_ccc(1, design_sawtooth_filter(decreasing=channel == 0)),
                blocks.complex_to_mag(1),
                blocks.float_to_complex(),  # So we can use the complex-input band filter. TODO eliminate this for efficiency
                MultistageChannelFilter(
                    input_rate=input_rate,
                    output_rate=audio_rate,
                    cutoff_freq=5000,
                    transition_width=5000),
                blocks.complex_to_real(),
                # assuming below 40Hz is not of interest
                grfilter.dc_blocker_ff(audio_rate // 40, False),
                (channel_joiner, channel))
Пример #7
0
 def __do_connect(self):
     inherent_gain = 0.5  # fudge factor so that our output is similar level to narrow FM
     if self.__demod_method != 'async':
         inherent_gain *= 2
     
     agc_block = analog.feedforward_agc_cc(int(.005 * self.__demod_rate), inherent_gain)
     
     # non-method-specific elements
     self.disconnect_all()
     self.connect(
         self,
         self.band_filter_block,  # from SimpleAudioDemodulator
         self.rf_squelch_block,  # from SquelchMixin
         agc_block)
     self.connect(self.band_filter_block, self.rf_probe_block)
     before_demod = agc_block
     
     if self.__demod_method == u'async':
         dc_blocker = self.__make_dc_blocker()
         self.connect(
             before_demod,
             blocks.complex_to_mag(1),
             dc_blocker)
         self.connect_audio_output(dc_blocker, dc_blocker)
         self.__pll = None
     else:
         # all other methods use carrier tracking
         # TODO: refine PLL parameters further
         pll = self.__pll = analog.pll_carriertracking_cc(.01 * pi, .1 * pi, -.1 * pi)
         pll.set_lock_threshold(dB(-20))
         # pll.squelch_enable(True)
         self.connect(before_demod, pll)
         
         if self.__demod_method == u'stereo':
             left_input, left_output = self.__make_sideband_demod(False)
             right_input, right_output = self.__make_sideband_demod(True)
             self.connect(pll, left_input)
             self.connect(pll, right_input)
             self.connect_audio_output(left_output, right_output)
         else:
             (demod_input, demod_output) = self.__make_sideband_demod(self.__demod_method == u'usb')
             self.connect(pll, demod_input)
             self.connect_audio_output(demod_output, demod_output)
Пример #8
0
 def __do_connect(self):
     inherent_gain = 0.5  # fudge factor so that our output is similar level to narrow FM
     if self.__demod_method != 'async':
         inherent_gain *= 2
     
     agc_block = analog.feedforward_agc_cc(int(.005 * self.__demod_rate), inherent_gain)
     
     # non-method-specific elements
     self.disconnect_all()
     self.connect(
         self,
         self.band_filter_block,  # from SimpleAudioDemodulator
         self.rf_squelch_block,  # from SquelchMixin
         agc_block)
     self.connect(self.band_filter_block, self.rf_probe_block)
     before_demod = agc_block
     
     if self.__demod_method == u'async':
         dc_blocker = self.__make_dc_blocker()
         self.connect(
             before_demod,
             blocks.complex_to_mag(1),
             dc_blocker)
         self.connect_audio_output(dc_blocker, dc_blocker)
         self.__pll = None
     else:
         # all other methods use carrier tracking
         # TODO: refine PLL parameters further
         pll = self.__pll = analog.pll_carriertracking_cc(.01 * pi, .1 * pi, -.1 * pi)
         pll.set_lock_threshold(dB(-20))
         # pll.squelch_enable(True)
         self.connect(before_demod, pll)
         
         if self.__demod_method == u'stereo':
             left_input, left_output = self.__make_sideband_demod(False)
             right_input, right_output = self.__make_sideband_demod(True)
             self.connect(pll, left_input)
             self.connect(pll, right_input)
             self.connect_audio_output(left_output, right_output)
         else:
             (demod_input, demod_output) = self.__make_sideband_demod(self.__demod_method == u'usb')
             self.connect(pll, demod_input)
             self.connect_audio_output(demod_output, demod_output)
Пример #9
0
    def __init__(self,
            input_rate,
            output_rate=12000,
            output_frequency=1500,
            transition_width=100,
            width=800):
        """Make a new WSPRFilter.

        input_rate: the incomming sample rate

        output_rate: output sample rate

        output_frequency: 0Hz in the complex input will be centered on this
        frequency in the real output

        width, transition_width: passband and transition band widths.
        """

        gr.hier_block2.__init__(
            self, type(self).__name__,
            gr.io_signature(1, 1, gr.sizeof_gr_complex),
            gr.io_signature(1, 1, gr.sizeof_float))

        self.connect(
            self,

            MultistageChannelFilter(
                input_rate=input_rate,
                output_rate=output_rate,
                cutoff_freq=width / 2,
                transition_width=transition_width),

            blocks.rotator_cc(2 * pi * output_frequency / output_rate),

            blocks.complex_to_real(vlen=1),

            analog.agc2_ff(
                reference=dB(-10),
                attack_rate=8e-1,
                decay_rate=8e-1),

            self)
Пример #10
0
    def __init__(self,
            input_rate,
            output_rate=12000,
            output_frequency=1500,
            transition_width=100,
            width=800):
        """Make a new WSPRFilter.

        input_rate: the incomming sample rate

        output_rate: output sample rate

        output_frequency: 0Hz in the complex input will be centered on this
        frequency in the real output

        width, transition_width: passband and transition band widths.
        """

        gr.hier_block2.__init__(
            self, type(self).__name__,
            gr.io_signature(1, 1, gr.sizeof_gr_complex),
            gr.io_signature(1, 1, gr.sizeof_float))

        self.connect(
            self,

            MultistageChannelFilter(
                input_rate=input_rate,
                output_rate=output_rate,
                cutoff_freq=width / 2,
                transition_width=transition_width),

            blocks.rotator_cc(2 * pi * output_frequency / output_rate),

            blocks.complex_to_real(vlen=1),

            analog.agc2_ff(
                reference=dB(-10),
                attack_rate=8e-1,
                decay_rate=8e-1),

            self)
Пример #11
0
    def __init__(self, mode, input_rate=0, context=None):
        assert input_rate > 0
        self.__input_rate = input_rate
        gr.hier_block2.__init__(
            self, type(self).__name__,
            gr.io_signature(1, 1, gr.sizeof_gr_complex),
            gr.io_signature(1, 1, gr.sizeof_float))
        
        channel_filter = self.__make_channel_filter()

        self.__text = u''
        self.__char_queue = gr.msg_queue(limit=100)
        self.__char_sink = blocks.message_sink(gr.sizeof_char, self.__char_queue, True)

        # The output of the channel filter is oversampled so we don't need to
        # interpolate for the audio monitor. So we'll downsample before going into
        # the demodulator.
        samp_per_sym = 8
        downsample = self.__demod_rate / samp_per_sym / self.__symbol_rate
        assert downsample % 1 == 0
        downsample = int(downsample)

        self.connect(
            self,
            channel_filter,
            blocks.keep_one_in_n(gr.sizeof_gr_complex, downsample),
            psk31_coherent_demodulator_cc(samp_per_sym=samp_per_sym),
            psk31_constellation_decoder_cb(
                varicode_decode=True,
                differential_decode=True),
            self.__char_sink)
        
        self.connect(
            channel_filter,
            blocks.rotator_cc(rotator_inc(self.__demod_rate, self.__audio_frequency)),
            blocks.complex_to_real(vlen=1),
            analog.agc2_ff(
                reference=dB(-10),
                attack_rate=8e-1,
                decay_rate=8e-1),
            self)
Пример #12
0
    def __init__(self, mode, input_rate=0, context=None):
        assert input_rate > 0
        self.__input_rate = input_rate
        gr.hier_block2.__init__(
            self, type(self).__name__,
            gr.io_signature(1, 1, gr.sizeof_gr_complex),
            gr.io_signature(1, 1, gr.sizeof_float))
        
        channel_filter = self.__make_channel_filter()

        self.__char_queue = gr.msg_queue(limit=100)
        self.__char_sink = blocks.message_sink(gr.sizeof_char, self.__char_queue, True)

        # The output of the channel filter is oversampled so we don't need to
        # interpolate for the audio monitor. So we'll downsample before going into
        # the demodulator.
        samp_per_sym = 8
        downsample = self.__demod_rate / samp_per_sym / self.__symbol_rate
        assert downsample % 1 == 0
        downsample = int(downsample)

        self.connect(
            self,
            channel_filter,
            blocks.keep_one_in_n(gr.sizeof_gr_complex, downsample),
            psk31_coherent_demodulator_cc(samp_per_sym=samp_per_sym),
            psk31_constellation_decoder_cb(
                varicode_decode=True,
                differential_decode=True),
            self.__char_sink)
        
        self.connect(
            channel_filter,
            blocks.rotator_cc(rotator_inc(self.__demod_rate, self.__audio_frequency)),
            blocks.complex_to_real(vlen=1),
            analog.agc2_ff(
                reference=dB(-10),
                attack_rate=8e-1,
                decay_rate=8e-1),
            self)
Пример #13
0
 def __init__(self, name):
     gr.hier_block2.__init__(
         self, name,
         gr.io_signature(0, 0, 0),
         gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
     )
     
     rf_rate = self.rf_rate
     audio_rate = self.audio_rate
     
     self.__noise_level = -22
     self.__transmitters = CellDict(dynamic=True)
     
     self.__transmitters_cs = CollectionState(self.__transmitters)
     
     self.__bus = blocks.add_vcc(1)
     self.__channel_model = channels.channel_model(
         noise_voltage=dB(self.__noise_level),
         frequency_offset=0,
         epsilon=1.01,  # TODO: expose this parameter
         # taps=...,  # TODO: apply something here?
     )
     self.__rotator = blocks.rotator_cc()
     self.__throttle = blocks.throttle(gr.sizeof_gr_complex, rf_rate)
     self.connect(
         self.__bus,
         self.__throttle,
         self.__channel_model,
         self.__rotator,
         self)
     signals = []
     
     def add_modulator(freq, key, mode_or_modulator_ctor, **kwargs):
         if isinstance(mode_or_modulator_ctor, type):
             mode = None
             ctor = mode_or_modulator_ctor
         else:
             mode = mode_or_modulator_ctor
             mode_def = lookup_mode(mode)
             if mode_def is None:  # missing plugin, say
                 return
             ctor = mode_def.mod_class
         context = None  # TODO implement context
         modulator = ctor(context=context, mode=mode, **kwargs)
         tx = _SimulatedTransmitter(modulator, audio_rate, rf_rate, freq)
         
         self.connect(audio_signal, tx)
         signals.append(tx)
         self.__transmitters[key] = tx
     
     # Audio input signal
     pitch = analog.sig_source_f(audio_rate, analog.GR_SAW_WAVE, -1, 2000, 1000)
     audio_signal = vco = blocks.vco_f(audio_rate, 1, 1)
     self.connect(pitch, vco)
     
     # Channels
     add_modulator(0.0, 'usb', 'USB')
     add_modulator(10e3, 'am', 'AM')
     add_modulator(30e3, 'fm', 'NFM')
     add_modulator(-30e3, 'vor1', 'VOR', angle=0)
     add_modulator(-60e3, 'vor2', 'VOR', angle=math.pi / 2)
     add_modulator(50e3, 'rtty', 'RTTY', message='The quick brown fox jumped over the lazy dog.\n')
     add_modulator(80e3, 'chirp', ChirpModulator)
     
     bus_input = 0
     for signal in signals:
         self.connect(signal, (self.__bus, bus_input))
         bus_input = bus_input + 1
     
     self.__signal_type = SignalType(
         kind='IQ',
         sample_rate=rf_rate)
     self.__usable_bandwidth = RangeT([(-rf_rate / 2, rf_rate / 2)])
Пример #14
0
 def set_gain(self, value):
     self.__mult.set_k(dB(value))
Пример #15
0
 def set_noise_level(self, value):
     self.__channel_model.set_noise_voltage(dB(value))
     self.__noise_level = value
Пример #16
0
 def __init__(self, mode='433', input_rate=0, context=None):
     assert input_rate > 0
     assert context is not None
     gr.hier_block2.__init__(
         self, type(self).__name__,
         gr.io_signature(1, 1, gr.sizeof_gr_complex),
         gr.io_signature(0, 0, 0))
     
     # The input bandwidth chosen is not primarily determined by the bandwidth of the input signals, but by the frequency error of the transmitters. Therefore it is not too critical, and we can choose the exact rate to make the filtering easy.
     if input_rate <= upper_preferred_demod_rate:
         # Skip having a filter at all.
         self.__band_filter = None
         demod_rate = input_rate
     else:
         # TODO: This gunk is very similar to the stuff that MultistageChannelFilter does. See if we can share some code.
         lower_rate = input_rate
         lower_rate_prev = None
         while lower_rate > upper_preferred_demod_rate and lower_rate != lower_rate_prev:
             lower_rate_prev = lower_rate
             if lower_rate % 5 == 0 and lower_rate > upper_preferred_demod_rate * 3:
                 lower_rate /= 5
             elif lower_rate % 2 == 0:
                 lower_rate /= 2
             else:
                 # non-integer ratio
                 lower_rate = upper_preferred_demod_rate
                 break
         demod_rate = lower_rate
         
         self.__band_filter = MultistageChannelFilter(
             input_rate=input_rate,
             output_rate=demod_rate,
             cutoff_freq=demod_rate * 0.4,
             transition_width=demod_rate * 0.2)
     
     # Subprocess
     # using /usr/bin/env because twisted spawnProcess doesn't support path search
     # pylint: disable=no-member
     process = the_reactor.spawnProcess(
         RTL433ProcessProtocol(context.output_message),
         '/usr/bin/env',
         env=None,  # inherit environment
         args=[
             'env', 'rtl_433',
             '-F', 'json',
             '-r', '-',  # read from stdin
             '-m', '3',  # complex float input
             '-s', str(demod_rate),
         ],
         childFDs={
             0: 'w',
             1: 'r',
             2: 2
         })
     sink = make_sink_to_process_stdin(process, itemsize=gr.sizeof_gr_complex)
     
     agc = analog.agc2_cc(reference=dB(-4))
     agc.set_attack_rate(200 / demod_rate)
     agc.set_decay_rate(200 / demod_rate)
     
     if self.__band_filter:
         self.connect(
             self,
             self.__band_filter,
             agc)
     else:
         self.connect(
             self,
             agc)
     self.connect(agc, sink)
Пример #17
0
    def __init__(self, mode='433', input_rate=0, context=None):
        assert input_rate > 0
        assert context is not None
        gr.hier_block2.__init__(self,
                                type(self).__name__,
                                gr.io_signature(1, 1, gr.sizeof_gr_complex),
                                gr.io_signature(0, 0, 0))

        # The input bandwidth chosen is not primarily determined by the bandwidth of the input signals, but by the frequency error of the transmitters. Therefore it is not too critical, and we can choose the exact rate to make the filtering easy.
        if input_rate <= upper_preferred_demod_rate:
            # Skip having a filter at all.
            self.__band_filter = None
            demod_rate = input_rate
        else:
            # TODO: This gunk is very similar to the stuff that MultistageChannelFilter does. See if we can share some code.
            lower_rate = input_rate
            lower_rate_prev = None
            while lower_rate > upper_preferred_demod_rate and lower_rate != lower_rate_prev:
                lower_rate_prev = lower_rate
                if lower_rate % 5 == 0 and lower_rate > upper_preferred_demod_rate * 3:
                    lower_rate /= 5
                elif lower_rate % 2 == 0:
                    lower_rate /= 2
                else:
                    # non-integer ratio
                    lower_rate = upper_preferred_demod_rate
                    break
            demod_rate = lower_rate

            self.__band_filter = MultistageChannelFilter(
                input_rate=input_rate,
                output_rate=demod_rate,
                cutoff_freq=demod_rate * 0.4,
                transition_width=demod_rate * 0.2)

        # Subprocess
        # using /usr/bin/env because twisted spawnProcess doesn't support path search
        # pylint: disable=no-member
        process = the_reactor.spawnProcess(
            RTL433ProcessProtocol(context.output_message),
            '/usr/bin/env',
            env=None,  # inherit environment
            args=[
                'env',
                'rtl_433',
                '-F',
                'json',
                '-r',
                '-',  # read from stdin
                '-m',
                '3',  # complex float input
                '-s',
                str(demod_rate),
            ],
            childFDs={
                0: 'w',
                1: 'r',
                2: 2
            })
        sink = make_sink_to_process_stdin(process,
                                          itemsize=gr.sizeof_gr_complex)

        agc = analog.agc2_cc(reference=dB(-4))
        agc.set_attack_rate(200 / demod_rate)
        agc.set_decay_rate(200 / demod_rate)

        if self.__band_filter:
            self.connect(self, self.__band_filter, agc)
        else:
            self.connect(self, agc)
        self.connect(agc, sink)
Пример #18
0
    def __init__(self, name):
        gr.hier_block2.__init__(
            self,
            name,
            gr.io_signature(0, 0, 0),
            gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
        )

        rf_rate = self.rf_rate
        audio_rate = self.audio_rate

        self.__noise_level = -22
        self.__transmitters = CellDict(dynamic=True)

        self.__transmitters_cs = CollectionState(self.__transmitters)

        self.__bus = blocks.add_vcc(1)
        self.__channel_model = channels.channel_model(
            noise_voltage=dB(self.__noise_level),
            frequency_offset=0,
            epsilon=1.01,  # TODO: expose this parameter
            # taps=...,  # TODO: apply something here?
        )
        self.__rotator = blocks.rotator_cc()
        self.__throttle = blocks.throttle(gr.sizeof_gr_complex, rf_rate)
        self.connect(self.__bus, self.__throttle, self.__channel_model,
                     self.__rotator, self)
        signals = []

        def add_modulator(freq, key, mode_or_modulator_ctor, **kwargs):
            if isinstance(mode_or_modulator_ctor, type):
                mode = None
                ctor = mode_or_modulator_ctor
            else:
                mode = mode_or_modulator_ctor
                mode_def = lookup_mode(mode)
                if mode_def is None:  # missing plugin, say
                    return
                ctor = mode_def.mod_class
            context = None  # TODO implement context
            modulator = ctor(context=context, mode=mode, **kwargs)
            tx = _SimulatedTransmitter(modulator, audio_rate, rf_rate, freq)

            self.connect(audio_signal, tx)
            signals.append(tx)
            self.__transmitters[key] = tx

        # Audio input signal
        pitch = analog.sig_source_f(audio_rate, analog.GR_SAW_WAVE, -1, 2000,
                                    1000)
        audio_signal = vco = blocks.vco_f(audio_rate, 1, 1)
        self.connect(pitch, vco)

        # Channels
        add_modulator(0.0, 'usb', 'USB')
        add_modulator(10e3, 'am', 'AM')
        add_modulator(30e3, 'fm', 'NFM')
        add_modulator(-30e3, 'vor1', 'VOR', angle=0)
        add_modulator(-60e3, 'vor2', 'VOR', angle=math.pi / 2)
        add_modulator(
            50e3,
            'rtty',
            'RTTY',
            message='The quick brown fox jumped over the lazy dog.\n')
        add_modulator(80e3, 'chirp', ChirpModulator)

        bus_input = 0
        for signal in signals:
            self.connect(signal, (self.__bus, bus_input))
            bus_input = bus_input + 1

        self.__signal_type = SignalType(kind='IQ', sample_rate=rf_rate)
        self.__usable_bandwidth = RangeT([(-rf_rate / 2, rf_rate / 2)])
Пример #19
0
 def set_gain(self, value):
     self.__mult.set_k(dB(value))
Пример #20
0
 def set_noise_level(self, value):
     self.__channel_model.set_noise_voltage(dB(value))
     self.__noise_level = value
Пример #21
0
 def __init__(self, mode, **kwargs):
     if mode == 'LSB':
         lsb = True
         cw = False
     elif mode == 'USB':
         lsb = False
         cw = False
     elif mode == 'CW':
         lsb = False
         cw = True
     else:
         raise ValueError('Not an SSB mode: %r' % (mode,))
     
     demod_rate = 8000  # round number close to SSB bandwidth * 2
     
     SimpleAudioDemodulator.__init__(self,
         mode=mode,
         audio_rate=demod_rate,
         demod_rate=demod_rate,
         band_filter=demod_rate / 2,  # note narrower filter applied later
         band_filter_transition=demod_rate / 2,
         **kwargs)
     
     if cw:
         self.__offset = 1500  # CW beat frequency
         half_bandwidth = self.half_bandwidth = 500
         band_filter_width = 120
         band_mid = 0
         agc_reference = dB(-10)
         agc_rate = 1e-1
     else:
         self.__offset = 0
         half_bandwidth = self.half_bandwidth = 2800 / 2  # standard SSB bandwidth
         band_filter_width = half_bandwidth / 5
         if lsb:
             band_mid = -200 - half_bandwidth
         else:
             band_mid = 200 + half_bandwidth
         agc_reference = dB(-8)
         agc_rate = 8e-1
     
     band_filter_low = band_mid - half_bandwidth
     band_filter_high = band_mid + half_bandwidth
     sharp_filter_block = grfilter.fir_filter_ccc(
         1,
         firdes.complex_band_pass(1.0, demod_rate,
             band_filter_low + self.__offset,
             band_filter_high + self.__offset,
             band_filter_width,
             firdes.WIN_HAMMING))
     self.__filter_shape = BandShape.bandpass_transition(
         low=band_filter_low,
         high=band_filter_high,
         transition=band_filter_width,
         markers={})
     
     self.agc_block = analog.agc2_cc(reference=agc_reference)
     self.agc_block.set_attack_rate(agc_rate)
     self.agc_block.set_decay_rate(agc_rate)
     self.agc_block.set_max_gain(dB(_ssb_max_agc))
     
     ssb_demod_block = blocks.complex_to_real(1)
     
     self.connect(
         self,
         self.band_filter_block,
         sharp_filter_block,
         # TODO: We would like to have a squelch which does not interfere with the AGC, but this is impossible without combining the squelch and AGC
         self.rf_squelch_block,
         self.agc_block,
         ssb_demod_block)
     self.connect(sharp_filter_block, self.rf_probe_block)
     self.connect_audio_output(ssb_demod_block)
Пример #22
0
    def __init__(self, mode, **kwargs):
        if mode == "LSB":
            lsb = True
            cw = False
        elif mode == "USB":
            lsb = False
            cw = False
        elif mode == "CW":
            lsb = False
            cw = True
        else:
            raise ValueError("Not an SSB mode: %r" % (mode,))

        demod_rate = 8000  # round number close to SSB bandwidth * 2

        SimpleAudioDemodulator.__init__(
            self,
            mode=mode,
            audio_rate=demod_rate,
            demod_rate=demod_rate,
            band_filter=demod_rate / 2,  # note narrower filter applied later
            band_filter_transition=demod_rate / 2,
            **kwargs
        )

        if cw:
            self.__offset = 1500  # CW beat frequency
            half_bandwidth = self.half_bandwidth = 500
            self.band_filter_width = 120
            band_mid = 0
            agc_reference = dB(-10)
            agc_rate = 1e-1
        else:
            self.__offset = 0
            half_bandwidth = self.half_bandwidth = 2800 / 2  # standard SSB bandwidth
            self.band_filter_width = half_bandwidth / 5
            if lsb:
                band_mid = -200 - half_bandwidth
            else:
                band_mid = 200 + half_bandwidth
            agc_reference = dB(-8)
            agc_rate = 8e-1

        self.band_filter_low = band_mid - half_bandwidth
        self.band_filter_high = band_mid + half_bandwidth
        sharp_filter_block = grfilter.fir_filter_ccc(
            1,
            firdes.complex_band_pass(
                1.0,
                demod_rate,
                self.band_filter_low + self.__offset,
                self.band_filter_high + self.__offset,
                self.band_filter_width,
                firdes.WIN_HAMMING,
            ),
        )

        self.agc_block = analog.agc2_cc(reference=agc_reference)
        self.agc_block.set_attack_rate(agc_rate)
        self.agc_block.set_decay_rate(agc_rate)
        self.agc_block.set_max_gain(dB(_ssb_max_agc))

        ssb_demod_block = blocks.complex_to_real(1)

        self.connect(
            self,
            self.band_filter_block,
            sharp_filter_block,
            # TODO: We would like to have an in
            self.rf_squelch_block,
            self.agc_block,
            ssb_demod_block,
        )
        self.connect(sharp_filter_block, self.rf_probe_block)
        self.connect_audio_output(ssb_demod_block)
Пример #23
0
    def __init__(self, mode, **kwargs):
        if mode == 'LSB':
            lsb = True
            cw = False
        elif mode == 'USB':
            lsb = False
            cw = False
        elif mode == 'CW':
            lsb = False
            cw = True
        else:
            raise ValueError('Not an SSB mode: %r' % (mode, ))

        demod_rate = 8000  # round number close to SSB bandwidth * 2

        SimpleAudioDemodulator.__init__(
            self,
            mode=mode,
            audio_rate=demod_rate,
            demod_rate=demod_rate,
            band_filter=demod_rate / 2,  # note narrower filter applied later
            band_filter_transition=demod_rate / 2,
            **kwargs)

        if cw:
            self.__offset = 1500  # CW beat frequency
            half_bandwidth = self.half_bandwidth = 500
            band_filter_width = 120
            band_mid = 0
            agc_reference = dB(-10)
            agc_rate = 1e-1
        else:
            self.__offset = 0
            half_bandwidth = self.half_bandwidth = 2800 / 2  # standard SSB bandwidth
            band_filter_width = half_bandwidth / 5
            if lsb:
                band_mid = -200 - half_bandwidth
            else:
                band_mid = 200 + half_bandwidth
            agc_reference = dB(-8)
            agc_rate = 8e-1

        band_filter_low = band_mid - half_bandwidth
        band_filter_high = band_mid + half_bandwidth
        sharp_filter_block = grfilter.fir_filter_ccc(
            1,
            firdes.complex_band_pass(1.0, demod_rate,
                                     band_filter_low + self.__offset,
                                     band_filter_high + self.__offset,
                                     band_filter_width, firdes.WIN_HAMMING))
        self.__filter_shape = BandShape.bandpass_transition(
            low=band_filter_low,
            high=band_filter_high,
            transition=band_filter_width,
            markers={})

        self.agc_block = analog.agc2_cc(reference=agc_reference)
        self.agc_block.set_attack_rate(agc_rate)
        self.agc_block.set_decay_rate(agc_rate)
        self.agc_block.set_max_gain(dB(_ssb_max_agc))

        ssb_demod_block = blocks.complex_to_real(1)

        self.connect(
            self,
            self.band_filter_block,
            sharp_filter_block,
            # TODO: We would like to have a squelch which does not interfere with the AGC, but this is impossible without combining the squelch and AGC
            self.rf_squelch_block,
            self.agc_block,
            ssb_demod_block)
        self.connect(sharp_filter_block, self.rf_probe_block)
        self.connect_audio_output(ssb_demod_block)
Пример #24
0
from gnuradio import analog
from gnuradio import gr
from gnuradio import blocks

from shinysdr.i.modes import get_modes, lookup_mode
from shinysdr.interfaces import IDemodulator, IDemodulatorContext, IDemodulatorModeChange, ITunableDemodulator
from shinysdr.math import dB, rotator_inc, to_dB
from shinysdr.signals import SignalType, no_signal
from shinysdr.types import EnumT, QuantityT, RangeT, ReferenceT
from shinysdr import units
from shinysdr.values import ExportedState, exported_value, setter, unserialize_exported_state


# arbitrary non-infinite limit
_audio_power_minimum_dB = -60
_audio_power_minimum_amplitude = dB(_audio_power_minimum_dB)


_dummy_audio_rate = 2000


class IReceiver(Interface):
    """
    Marker interface for receivers.
    
    (This exists even though Receiver has no class hierarchy because the client would like to know what's a receiver block, and interface information is automatically delivered to the client.)
    """


@implementer(IReceiver)
class Receiver(gr.hier_block2, ExportedState):
Пример #25
0
from gnuradio import analog
from gnuradio import gr
from gnuradio import blocks

from shinysdr.i.modes import get_modes, lookup_mode
from shinysdr.interfaces import ITunableDemodulator
from shinysdr.math import dB, rotator_inc, to_dB
from shinysdr.signals import SignalType
from shinysdr.types import EnumT, QuantityT, RangeT, ReferenceT
from shinysdr import units
from shinysdr.values import ExportedState, exported_value, setter, unserialize_exported_state

# arbitrary non-infinite limit
_audio_power_minimum_dB = -60
_audio_power_minimum_amplitude = dB(_audio_power_minimum_dB)

_dummy_audio_rate = 2000


class IReceiver(Interface):
    """
    Marker interface for receivers.
    
    (This exists even though Receiver has no class hierarchy because the client would like to know what's a receiver block, and interface information is automatically delivered to the client.)
    """


class Receiver(gr.hier_block2, ExportedState):
    implements(IReceiver)
Пример #26
0
    def __init__(self, mode, **kwargs):
        if mode == 'LSB':
            lsb = True
            cw = False
        elif mode == 'USB':
            lsb = False
            cw = False
        elif mode == 'CW':
            lsb = False
            cw = True
        else:
            raise ValueError('Not an SSB mode: %r' % (mode, ))

        demod_rate = 8000  # round number close to SSB bandwidth * 2

        SimpleAudioDemodulator.__init__(
            self,
            mode=mode,
            audio_rate=demod_rate,
            demod_rate=demod_rate,
            band_filter=demod_rate / 2,  # note narrower filter applied later
            band_filter_transition=demod_rate / 2,
            **kwargs)

        if cw:
            self.__offset = 1500  # CW beat frequency
            half_bandwidth = self.half_bandwidth = 500
            self.band_filter_width = 120
            band_mid = 0
            agc_reference = dB(-13)
        else:
            self.__offset = 0
            half_bandwidth = self.half_bandwidth = 2800 / 2  # standard SSB bandwidth
            self.band_filter_width = half_bandwidth / 5
            if lsb:
                band_mid = -200 - half_bandwidth
            else:
                band_mid = 200 + half_bandwidth
            agc_reference = dB(-8)

        self.band_filter_low = band_mid - half_bandwidth
        self.band_filter_high = band_mid + half_bandwidth
        sharp_filter_block = grfilter.fir_filter_ccc(
            1,
            firdes.complex_band_pass(1.0, demod_rate,
                                     self.band_filter_low + self.__offset,
                                     self.band_filter_high + self.__offset,
                                     self.band_filter_width,
                                     firdes.WIN_HAMMING))

        self.agc_block = analog.agc2_cc(reference=agc_reference)
        self.agc_block.set_attack_rate(1e-1)
        self.agc_block.set_decay_rate(1e-1)
        self.agc_block.set_max_gain(dB(_ssb_max_agc))

        ssb_demod_block = blocks.complex_to_real(1)

        self.connect(self, self.band_filter_block, sharp_filter_block,
                     self.rf_squelch_block, self.agc_block, ssb_demod_block)
        self.connect(sharp_filter_block, self.rf_probe_block)
        self.connect_audio_output(ssb_demod_block)