def setupService(self, mode, frequency, source): logger.debug("setting up service {0} on frequency {1}".format( mode, frequency)) # TODO selecting outputs will need some more intelligence here if mode == "packet": output = AprsServiceOutput(frequency) elif mode == "js8": output = Js8ServiceOutput(frequency) else: output = WsjtServiceOutput(frequency) d = Dsp(output) d.nc_port = source.getPort() center_freq = source.getProps()["center_freq"] d.set_offset_freq(frequency - center_freq) d.set_center_freq(center_freq) modeObject = Modes.findByModulation(mode) d.set_demodulator(modeObject.get_modulation()) d.set_bandpass(modeObject.get_bandpass()) d.set_secondary_demodulator(mode) d.set_audio_compression("none") d.set_samp_rate(source.getProps()["samp_rate"]) d.set_temporary_directory(CoreConfig().get_temporary_directory()) d.set_service() d.start() return d
def __init__(self, active_dsp, mode_str: str): self.read_fn = None self.doRun = True self.dsp = active_dsp self.writers = [] mode = Modes.findByModulation(mode_str) if mode is None or not isinstance(mode, AudioChopperMode): raise ValueError( "Mode {} is not an audio chopper mode".format(mode_str)) self.profile_source = mode.get_profile_source() (self.outputReader, self.outputWriter) = Pipe() super().__init__()
def render_table(self): bookmarks = Bookmarks.getSharedInstance().getBookmarks() emptyText = """ <tr class="emptytext"><td colspan="4"> No bookmarks in storage. You can add new bookmarks using the buttons below. </td></tr> """ return """ <table class="table" data-modes='{modes}'> <tr> <th>Name</th> <th class="frequency">Frequency</th> <th>Modulation</th> <th>Actions</th> </tr> {bookmarks} </table> """.format( bookmarks="".join(self.render_bookmark(b) for b in bookmarks) if bookmarks else emptyText, modes=json.dumps({m.modulation: m.name for m in Modes.getAvailableModes()}), )
def render_input(self, value, errors): def render_mode(m): return """ <option value={mode}>{name}</option> """.format( mode=m.modulation, name=m.name, ) return """ <input type="hidden" class="{classes}" id="{id}" name="{id}" value="{value}" {disabled}> <div class="inputs" style="display:none;"> <select class="form-control form-control-sm">{options}</select> <input class="form-control form-control-sm" type="number" step="1"> </div> """.format(id=self.id, classes=self.input_classes(errors), value=html.escape(value), options="".join( render_mode(m) for m in Modes.getAvailableModes() if isinstance(m, WsjtMode)), disabled="disabled" if self.disabled else "")
def __init__(self, handler, sdrSource): self.handler = handler self.sdrSource = sdrSource self.props = PropertyStack() # current audio mode. should be "audio" or "hd_audio" depending on what demodulatur is in use. self.audioOutput = None # local demodulator properties not forwarded to the sdr # ensure strict validation since these can be set from the client # and are used to build executable commands validators = { "output_rate": "int", "hd_output_rate": "int", "squelch_level": "num", "secondary_mod": ModulationValidator(), "low_cut": "num", "high_cut": "num", "offset_freq": "int", "mod": ModulationValidator(), "secondary_offset_freq": "int", "dmr_filter": "int", } self.localProps = PropertyValidator( PropertyLayer().filter(*validators.keys()), validators) self.props.addLayer(0, self.localProps) # properties that we inherit from the sdr self.props.addLayer( 1, self.sdrSource.getProps().filter( "audio_compression", "fft_compression", "digimodes_fft_size", "samp_rate", "center_freq", "start_mod", "start_freq", "wfm_deemphasis_tau", "digital_voice_codecserver", ), ) # defaults for values that may not be set self.props.addLayer( 2, PropertyLayer( output_rate=12000, hd_output_rate=48000, digital_voice_codecserver="", ).readonly()) self.chain = ClientDemodulatorChain(self._getDemodulator("nfm"), self.props["samp_rate"], self.props["output_rate"], self.props["hd_output_rate"], self.props["audio_compression"], self) self.readers = {} if "start_mod" in self.props: mode = Modes.findByModulation(self.props["start_mod"]) if mode: self.setDemodulator(mode.get_modulation()) if isinstance(mode, DigitalMode): self.setSecondaryDemodulator(mode.modulation) if mode.bandpass: bpf = [mode.bandpass.low_cut, mode.bandpass.high_cut] self.chain.setBandpass(*bpf) else: # TODO modes should be mandatory self.setDemodulator(self.props["start_mod"]) if "start_freq" in self.props and "center_freq" in self.props: self.chain.setFrequencyOffset(self.props["start_freq"] - self.props["center_freq"]) else: self.chain.setFrequencyOffset(0) self.subscriptions = [ self.props.wireProperty("audio_compression", self.setAudioCompression), self.props.wireProperty("fft_compression", self.chain.setSecondaryFftCompression), self.props.wireProperty("fft_voverlap_factor", self.chain.setSecondaryFftOverlapFactor), self.props.wireProperty("fft_fps", self.chain.setSecondaryFftFps), self.props.wireProperty("digimodes_fft_size", self.setSecondaryFftSize), self.props.wireProperty("samp_rate", self.chain.setSampleRate), self.props.wireProperty("output_rate", self.chain.setOutputRate), self.props.wireProperty("hd_output_rate", self.chain.setHdOutputRate), self.props.wireProperty("offset_freq", self.chain.setFrequencyOffset), self.props.wireProperty("center_freq", self.chain.setCenterFrequency), self.props.wireProperty("squelch_level", self.chain.setSquelchLevel), self.props.wireProperty("low_cut", self.chain.setLowCut), self.props.wireProperty("high_cut", self.chain.setHighCut), self.props.wireProperty("mod", self.setDemodulator), self.props.wireProperty("dmr_filter", self.chain.setSlotFilter), self.props.wireProperty("wfm_deemphasis_tau", self.chain.setWfmDeemphasisTau), self.props.wireProperty("secondary_mod", self.setSecondaryDemodulator), self.props.wireProperty("secondary_offset_freq", self.chain.setSecondaryFrequencyOffset), ] # wire power level output buffer = Buffer(Format.FLOAT) self.chain.setPowerWriter(buffer) self.wireOutput("smeter", buffer) # wire meta output buffer = Buffer(Format.CHAR) self.chain.setMetaWriter(buffer) self.wireOutput("meta", buffer) # wire secondary FFT buffer = Buffer(self.chain.getSecondaryFftOutputFormat()) self.chain.setSecondaryFftWriter(buffer) self.wireOutput("secondary_fft", buffer) # wire secondary demodulator buffer = Buffer(Format.CHAR) self.chain.setSecondaryWriter(buffer) self.wireOutput("secondary_demod", buffer) self.startOnAvailable = False self.sdrSource.addClient(self)