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()
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
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) + ' (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) @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
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()
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()
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()