Exemple #1
0
    def __init__(self, mode, input_rate=0, context=None):
        assert input_rate > 0
        assert context is not None
        gr.hier_block2.__init__(
            self,
            str(mode) + ' (FM + Multimon-NG) demodulator',
            gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
            gr.io_signature(1, 1, gr.sizeof_float * 1),
        )
        self.mode = mode
        self.input_rate = input_rate

        # FM demod
        # TODO: Retry telling the NFMDemodulator to have its output rate be pipe_rate instead of using a resampler. Something went wrong when trying that before. Same thing is done in dsd.py
        self.fm_demod = NFMDemodulator(
            mode='NFM',
            input_rate=input_rate,
            no_audio_filter=True,  # don't remove CTCSS tone
            tau=None)  # no deemphasis
        assert self.fm_demod.get_output_type().get_kind() == 'MONO'
        fm_audio_rate = self.fm_demod.get_output_type().get_sample_rate()

        # Subprocess
        self.mm_demod = APRSDemodulator(context=context)
        mm_audio_rate = self.mm_demod.get_input_type().get_sample_rate()

        # Output
        self.connect(self, self.fm_demod,
                     make_resampler(fm_audio_rate, mm_audio_rate),
                     self.mm_demod, self)
Exemple #2
0
class DSDDemodulator(gr.hier_block2, ExportedState):
    def __init__(self, mode, 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),
                                gr.io_signature(1, 1, gr.sizeof_float))

        # TODO: Retry telling the NFMDemodulator to have its output rate be pipe_rate instead of using a resampler. Something went wrong when trying that before. Same thing is done in multimon.py
        self.__fm_demod = NFMDemodulator(
            mode='NFM',
            input_rate=input_rate,
            no_audio_filter=True,  # don't remove CTCSS tone
            tau=None)  # no deemphasis
        assert self.__fm_demod.get_output_type().get_kind() == 'MONO'
        fm_audio_rate = self.__fm_demod.get_output_type().get_sample_rate()

        self.__output_type = SignalType(kind='MONO', sample_rate=8000)

        self.connect(self, self.__fm_demod,
                     make_resampler(fm_audio_rate, _demod_rate),
                     dsd_block_ff(), self)

    @exported_value(type=ReferenceT(), changes='never')
    def get_fm_demod(self):
        return self.__fm_demod

    def get_output_type(self):
        return self.__output_type

    @exported_value(type=BandShape, changes='never')
    def get_band_shape(self):
        return self.__fm_demod.get_band_shape()
Exemple #3
0
class FMAPRSDemodulator(gr.hier_block2, ExportedState):
    implements(IDemodulator)

    def __init__(self,
                 mode,
                 input_rate=0,
                 aprs_information=None,
                 context=None):
        assert input_rate > 0
        gr.hier_block2.__init__(
            self,
            str(mode) + ' (FM + Multimon-NG) demodulator',
            gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
            gr.io_signature(1, 1, gr.sizeof_float * 1),
        )
        self.mode = mode
        self.input_rate = input_rate

        # FM demod
        # TODO: Retry telling the NFMDemodulator to have its output rate be pipe_rate instead of using a resampler. Something went wrong when trying that before.
        self.fm_demod = NFMDemodulator(
            mode='NFM',
            input_rate=input_rate,
            no_audio_filter=True,  # don't remove CTCSS tone
            tau=None)  # no deemphasis
        assert self.fm_demod.get_output_type().get_kind() == 'MONO'
        fm_audio_rate = self.fm_demod.get_output_type().get_sample_rate()

        # Subprocess
        self.mm_demod = APRSDemodulator(aprs_information=aprs_information)
        mm_audio_rate = self.mm_demod.get_input_type().get_sample_rate()

        # Output
        self.connect(self, self.fm_demod,
                     make_resampler(fm_audio_rate, mm_audio_rate),
                     self.mm_demod, self)

    def state_def(self, callback):
        super(FMAPRSDemodulator, self).state_def(callback)
        # TODO make this possible to be decorator style
        callback(BlockCell(self, 'mm_demod'))

    def can_set_mode(self, mode):
        return False

    def get_half_bandwidth(self):
        return self.fm_demod.get_half_bandwidth()

    def get_output_type(self):
        return self.mm_demod.get_output_type()

    @exported_value()
    def get_band_filter_shape(self):
        return self.fm_demod.get_band_filter_shape()
Exemple #4
0
class FMAPRSDemodulator(gr.hier_block2, ExportedState):
    implements(IDemodulator)
    
    def __init__(self, mode, input_rate=0, aprs_information=None, context=None):
        assert input_rate > 0
        gr.hier_block2.__init__(
            self, str(mode) + ' (FM + Multimon-NG) demodulator',
            gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
            gr.io_signature(1, 1, gr.sizeof_float * 1),
        )
        self.mode = mode
        self.input_rate = input_rate
        
        # FM demod
        # TODO: Retry telling the NFMDemodulator to have its output rate be pipe_rate instead of using a resampler. Something went wrong when trying that before.
        self.fm_demod = NFMDemodulator(
            mode='NFM',
            input_rate=input_rate,
            no_audio_filter=True,  # don't remove CTCSS tone
            tau=None)  # no deemphasis
        assert self.fm_demod.get_output_type().get_kind() == 'MONO'
        fm_audio_rate = self.fm_demod.get_output_type().get_sample_rate()
        
        # Subprocess
        self.mm_demod = APRSDemodulator(
            aprs_information=aprs_information)
        mm_audio_rate = self.mm_demod.get_input_type().get_sample_rate()
        
        # Output
        self.connect(
            self,
            self.fm_demod,
            make_resampler(fm_audio_rate, mm_audio_rate),
            self.mm_demod,
            self)
    
    def state_def(self, callback):
        super(FMAPRSDemodulator, self).state_def(callback)
        # TODO make this possible to be decorator style
        callback(BlockCell(self, 'mm_demod'))
    
    def can_set_mode(self, mode):
        return False
    
    def get_half_bandwidth(self):
        return self.fm_demod.get_half_bandwidth()
    
    def get_output_type(self):
        return self.mm_demod.get_output_type()
    
    @exported_value()
    def get_band_filter_shape(self):
        return self.fm_demod.get_band_filter_shape()
Exemple #5
0
class MultimonNGDemodulator(gr.hier_block2, ExportedState):
	implements(IDemodulator)
	
	def __init__(self, mode, input_rate=0, audio_rate=0, context=None):
		assert input_rate > 0
		gr.hier_block2.__init__(
			self, str(mode) + ' (Multimon-NG) demodulator',
			gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
			# TODO: Add generic support for demodulators with no audio output
			gr.io_signature(2, 2, gr.sizeof_float * 1),
		)
		self.mode = mode
		self.input_rate = input_rate
		
		# FM demod
		self.fm_demod = NFMDemodulator(
			mode='NFM',
			input_rate=input_rate,
			audio_rate=pipe_rate,
			tau=None)  # no deemphasis
		
		# Subprocess
		self.process = SubprocessSink(
			args=['multimon-ng', '-t', 'raw', '-a', 'AFSK1200', '-A', '-v', '10', '-'],
			#args=['python', '../play16bit.py'],
			itemsize=gr.sizeof_short)
		
		# Output
		converter = blocks.float_to_short(vlen=1, scale=int_scale)
		self.connect(
			self,
			self.fm_demod,
			converter,
			self.process)
		# Dummy sink for useless stereo output of demod
		self.connect((self.fm_demod, 1), blocks.null_sink(gr.sizeof_float))
		# Audio copy output
		resampler = make_resampler(pipe_rate, audio_rate)
		self.connect(converter, blocks.short_to_float(vlen=1, scale=int_scale), resampler)
		#self.connect(self.fm_demod, resampler)
		self.connect(resampler, (self, 0))
		self.connect(resampler, (self, 1))
	
	def can_set_mode(self, mode):
		return False
	
	def get_half_bandwidth(self):
		return self.fm_demod.get_half_bandwidth()
	
	@exported_value()
	def get_band_filter_shape(self):
		return self.fm_demod.get_band_filter_shape()
Exemple #6
0
class FMAPRSDemodulator(gr.hier_block2, ExportedState):
    implements(IDemodulator)
    
    def __init__(self, mode, input_rate=0, context=None):
        assert input_rate > 0
        assert context is not None
        gr.hier_block2.__init__(
            self, str(mode) + ' (FM + Multimon-NG) demodulator',
            gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
            gr.io_signature(1, 1, gr.sizeof_float * 1),
        )
        self.mode = mode
        self.input_rate = input_rate
        
        # FM demod
        # TODO: Retry telling the NFMDemodulator to have its output rate be pipe_rate instead of using a resampler. Something went wrong when trying that before. Same thing is done in dsd.py
        self.fm_demod = NFMDemodulator(
            mode='NFM',
            input_rate=input_rate,
            no_audio_filter=True,  # don't remove CTCSS tone
            tau=None)  # no deemphasis
        assert self.fm_demod.get_output_type().get_kind() == 'MONO'
        fm_audio_rate = self.fm_demod.get_output_type().get_sample_rate()
        
        # Subprocess
        self.mm_demod = APRSDemodulator(context=context)
        mm_audio_rate = self.mm_demod.get_input_type().get_sample_rate()
        
        # Output
        self.connect(
            self,
            self.fm_demod,
            make_resampler(fm_audio_rate, mm_audio_rate),
            self.mm_demod,
            self)
    
    def can_set_mode(self, mode):
        return False
    
    def get_half_bandwidth(self):
        return self.fm_demod.get_half_bandwidth()
    
    def get_output_type(self):
        return self.mm_demod.get_output_type()
    
    @exported_block()
    def get_mm_demod(self):
        return self.mm_demod
    
    @exported_value()
    def get_band_filter_shape(self):
        return self.fm_demod.get_band_filter_shape()
Exemple #7
0
class FMAPRSDemodulator(gr.hier_block2, ExportedState):
    def __init__(self, mode, input_rate=0, context=None):
        assert input_rate > 0
        assert context is not None
        gr.hier_block2.__init__(
            self, str(mode) + b' (FM + Multimon-NG) demodulator',
            gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
            gr.io_signature(1, 1, gr.sizeof_float * 1),
        )
        self.mode = mode
        self.input_rate = input_rate
        
        # FM demod
        # TODO: Retry telling the NFMDemodulator to have its output rate be pipe_rate instead of using a resampler. Something went wrong when trying that before. Same thing is done in dsd.py
        self.fm_demod = NFMDemodulator(
            mode='NFM',
            input_rate=input_rate,
            no_audio_filter=True,  # don't remove CTCSS tone
            tau=None)  # no deemphasis
        assert self.fm_demod.get_output_type().get_kind() == 'MONO'
        fm_audio_rate = self.fm_demod.get_output_type().get_sample_rate()
        
        # Subprocess
        self.mm_demod = APRSDemodulator(context=context)
        mm_audio_rate = self.mm_demod.get_input_type().get_sample_rate()
        
        # Output
        self.connect(
            self,
            self.fm_demod,
            make_resampler(fm_audio_rate, mm_audio_rate),
            self.mm_demod,
            self)
    
    def _close(self):
        # TODO: This never gets called except in tests. Do this better, like by having an explicit life cycle for demodulators.
        self.mm_demod._close()
    
    @exported_value(type=BandShape, changes='never')
    def get_band_shape(self):
        return self.fm_demod.get_band_shape()
    
    def get_output_type(self):
        return self.mm_demod.get_output_type()
    
    @exported_value(type=ReferenceT(), changes='never')
    def get_mm_demod(self):
        return self.mm_demod
Exemple #8
0
 def __init__(self, mode, input_rate=0, aprs_information=None, context=None):
     assert input_rate > 0
     gr.hier_block2.__init__(
         self, str(mode) + ' (FM + Multimon-NG) demodulator',
         gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
         gr.io_signature(1, 1, gr.sizeof_float * 1),
     )
     self.mode = mode
     self.input_rate = input_rate
     
     # FM demod
     # TODO: Retry telling the NFMDemodulator to have its output rate be pipe_rate instead of using a resampler. Something went wrong when trying that before.
     self.fm_demod = NFMDemodulator(
         mode='NFM',
         input_rate=input_rate,
         no_audio_filter=True,  # don't remove CTCSS tone
         tau=None)  # no deemphasis
     assert self.fm_demod.get_output_type().get_kind() == 'MONO'
     fm_audio_rate = self.fm_demod.get_output_type().get_sample_rate()
     
     # Subprocess
     self.mm_demod = APRSDemodulator(
         aprs_information=aprs_information)
     mm_audio_rate = self.mm_demod.get_input_type().get_sample_rate()
     
     # Output
     self.connect(
         self,
         self.fm_demod,
         make_resampler(fm_audio_rate, mm_audio_rate),
         self.mm_demod,
         self)
Exemple #9
0
    def __init__(self, mode, input_rate=0, audio_rate=0, context=None):
        assert input_rate > 0
        gr.hier_block2.__init__(
            self,
            str(mode) + " (Multimon-NG) demodulator",
            gr.io_signature(1, 1, gr.sizeof_gr_complex * 1),
            # TODO: Add generic support for demodulators with no audio output
            gr.io_signature(2, 2, gr.sizeof_float * 1),
        )
        self.mode = mode
        self.input_rate = input_rate

        # FM demod
        self.fm_demod = NFMDemodulator(
            mode="NFM", input_rate=input_rate, audio_rate=pipe_rate, tau=None
        )  # no deemphasis

        # Subprocess
        self.process = SubprocessSink(
            args=["multimon-ng", "-t", "raw", "-a", "AFSK1200", "-A", "-v", "10", "-"],
            # args=['python', '../play16bit.py'],
            itemsize=gr.sizeof_short,
        )

        # Output
        converter = blocks.float_to_short(vlen=1, scale=int_scale)
        self.connect(self, self.fm_demod, converter, self.process)
        # Dummy sink for useless stereo output of demod
        self.connect((self.fm_demod, 1), blocks.null_sink(gr.sizeof_float))
        # Audio copy output
        resampler = make_resampler(pipe_rate, audio_rate)
        self.connect(converter, blocks.short_to_float(vlen=1, scale=int_scale), resampler)
        # self.connect(self.fm_demod, resampler)
        self.connect(resampler, (self, 0))
        self.connect(resampler, (self, 1))
Exemple #10
0
class DSDDemodulator(gr.hier_block2, ExportedState):
    implements(IDemodulator)
    
    def __init__(self, mode, 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),
            gr.io_signature(1, 1, gr.sizeof_float))
        
        # TODO: Retry telling the NFMDemodulator to have its output rate be pipe_rate instead of using a resampler. Something went wrong when trying that before. Same thing is done in multimon.py
        self.__fm_demod = NFMDemodulator(
            mode='NFM',
            input_rate=input_rate,
            no_audio_filter=True,  # don't remove CTCSS tone
            tau=None)  # no deemphasis
        assert self.__fm_demod.get_output_type().get_kind() == 'MONO'
        fm_audio_rate = self.__fm_demod.get_output_type().get_sample_rate()

        self.__output_type = SignalType(kind='MONO', sample_rate=8000)
        
        self.connect(
            self,
            self.__fm_demod,
            make_resampler(fm_audio_rate, _demod_rate),
            dsd_block_ff(),
            self)
    
    @exported_block()
    def get_fm_demod(self):
        return self.__fm_demod
    
    def can_set_mode(self, mode):
        return False
    
    def get_output_type(self):
        return self.__output_type
    
    def get_half_bandwidth(self):
        return self.__fm_demod.get_half_bandwidth()
    
    @exported_value()
    def get_band_filter_shape(self):
        return self.__fm_demod.get_band_filter_shape()
Exemple #11
0
    def __init__(self, mode, input_rate=0, uvquality=3, context=None):
        assert input_rate > 0
        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.__context = context
        self.__output_type = SignalType(kind='MONO', sample_rate=8000)
        self.__uvquality = uvquality

        # TODO: Retry telling the NFMDemodulator to have its output rate be _demod_rate instead of using a resampler. Something went wrong when trying that before. Same thing is done in multimon.py
        self.__fm_demod = NFMDemodulator(
            mode='NFM',
            input_rate=input_rate,
            no_audio_filter=True,  # don't remove CTCSS tone
            tau=None)  # no deemphasis
        assert self.__fm_demod.get_output_type().get_kind() == 'MONO'
        fm_audio_rate = self.__fm_demod.get_output_type().get_sample_rate()
        self.__resampler = make_resampler(fm_audio_rate, _demod_rate)

        self.__do_connect()
Exemple #12
0
 def __init__(self, mode, input_rate=0, uvquality=3, context=None):
     assert input_rate > 0
     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.__context = context
     self.__output_type = SignalType(kind='MONO', sample_rate=8000)
     self.__uvquality = uvquality
     
     # TODO: Retry telling the NFMDemodulator to have its output rate be _demod_rate instead of using a resampler. Something went wrong when trying that before. Same thing is done in multimon.py
     self.__fm_demod = NFMDemodulator(
         mode='NFM',
         input_rate=input_rate,
         no_audio_filter=True,  # don't remove CTCSS tone
         tau=None)  # no deemphasis
     assert self.__fm_demod.get_output_type().get_kind() == 'MONO'
     fm_audio_rate = self.__fm_demod.get_output_type().get_sample_rate()
     self.__resampler = make_resampler(fm_audio_rate, _demod_rate)
     
     self.__do_connect(False)
Exemple #13
0
class DSDDemodulator(gr.hier_block2, ExportedState):
    def __init__(self, mode, input_rate=0, uvquality=3, context=None):
        assert input_rate > 0
        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.__context = context
        self.__output_type = SignalType(kind='MONO', sample_rate=8000)
        self.__uvquality = uvquality

        # TODO: Retry telling the NFMDemodulator to have its output rate be _demod_rate instead of using a resampler. Something went wrong when trying that before. Same thing is done in multimon.py
        self.__fm_demod = NFMDemodulator(
            mode='NFM',
            input_rate=input_rate,
            no_audio_filter=True,  # don't remove CTCSS tone
            tau=None)  # no deemphasis
        assert self.__fm_demod.get_output_type().get_kind() == 'MONO'
        fm_audio_rate = self.__fm_demod.get_output_type().get_sample_rate()
        self.__resampler = make_resampler(fm_audio_rate, _demod_rate)

        self.__do_connect()

    def __do_connect(self):
        self.__context.lock()
        try:
            self.disconnect_all()
            if _available_version == 1:
                # backwards compatibility
                decoder = dsd_block_ff()
            else:
                decoder = dsd_block_ff(
                    # TODO: Add controls to choose frame and mod options at runtime — need to be able to get the enum info from gr-dsd, which may not even be currently available.
                    frame=dsd.dsd_FRAME_AUTO_DETECT,
                    mod=dsd.dsd_MOD_AUTO_SELECT,
                    uvquality=self.__uvquality,
                    errorbars=_debug_print,
                    verbosity=2 if _debug_print else 0)
            self.connect(self, self.__fm_demod, self.__resampler, decoder,
                         self)
        finally:
            self.__context.unlock()

    @exported_value(type=ReferenceT(), changes='never')
    def get_fm_demod(self):
        return self.__fm_demod

    if _available_version >= 2:

        @exported_value(type=_uvquality_range,
                        changes='this_setter',
                        label='Unvoiced speech quality',
                        parameter='uvquality')
        def get_uvquality(self):
            return self.__uvquality

        @setter
        def set_uvquality(self, value):
            value = _uvquality_range(value)
            if self.__uvquality != value:
                self.__uvquality = value
                self.__do_connect()

    def get_output_type(self):
        return self.__output_type

    @exported_value(type=BandShape, changes='never')
    def get_band_shape(self):
        return self.__fm_demod.get_band_shape()
Exemple #14
0
class DSDDemodulator(gr.hier_block2, ExportedState):
    def __init__(self, mode, input_rate=0, uvquality=3, context=None):
        assert input_rate > 0
        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.__context = context
        self.__output_type = SignalType(kind='MONO', sample_rate=8000)
        self.__uvquality = uvquality
        
        # TODO: Retry telling the NFMDemodulator to have its output rate be _demod_rate instead of using a resampler. Something went wrong when trying that before. Same thing is done in multimon.py
        self.__fm_demod = NFMDemodulator(
            mode='NFM',
            input_rate=input_rate,
            no_audio_filter=True,  # don't remove CTCSS tone
            tau=None)  # no deemphasis
        assert self.__fm_demod.get_output_type().get_kind() == 'MONO'
        fm_audio_rate = self.__fm_demod.get_output_type().get_sample_rate()
        self.__resampler = make_resampler(fm_audio_rate, _demod_rate)
        
        self.__do_connect(False)
    
    def __do_connect(self, not_init):
        # TODO: figure out why tests, but not the real server, have a hanging problem if we lock always
        if not_init: self.__context.lock()
        try:
            self.disconnect_all()
            if _available_version == 1:
                # backwards compatibility
                decoder = dsd_block_ff()
            else:
                decoder = dsd_block_ff(
                    # TODO: Add controls to choose frame and mod options at runtime — need to be able to get the enum info from gr-dsd, which may not even be currently available.
                    frame=dsd.dsd_FRAME_AUTO_DETECT,
                    mod=dsd.dsd_MOD_AUTO_SELECT,
                    uvquality=self.__uvquality,
                    errorbars=_debug_print,
                    verbosity=2 if _debug_print else 0)
            self.connect(
                self,
                self.__fm_demod,
                self.__resampler,
                decoder,
                self)
        finally:
            if not_init: self.__context.unlock()
    
    @exported_value(type=ReferenceT(), changes='never')
    def get_fm_demod(self):
        return self.__fm_demod
    
    if _available_version and _available_version >= 2:
        @exported_value(type=_uvquality_range,
            changes='this_setter',
            label='Unvoiced speech quality',
            parameter='uvquality')
        def get_uvquality(self):
            return self.__uvquality
    
        @setter
        def set_uvquality(self, value):
            value = _uvquality_range(value)
            if self.__uvquality != value:
                self.__uvquality = value
                self.__do_connect(True)
    
    def get_output_type(self):
        return self.__output_type
    
    @exported_value(type=BandShape, changes='never')
    def get_band_shape(self):
        return self.__fm_demod.get_band_shape()