diff --git a/op25/gr-op25_repeater/apps/gr_gnuplot.py b/op25/gr-op25_repeater/apps/gr_gnuplot.py index 3104560..c3fcb9f 100644 --- a/op25/gr-op25_repeater/apps/gr_gnuplot.py +++ b/op25/gr-op25_repeater/apps/gr_gnuplot.py @@ -166,6 +166,15 @@ class wrap_gp(object): s += '%f\n' % (b) s += 'e\n' plots.append('"-" with points') + elif mode == 'fftf': + self.ffts = np.fft.rfft(self.buf * np.blackman(BUFSZ)) / (0.42 * BUFSZ) + #self.ffts = np.fft.fftshift(self.ffts) + self.ffts = np.abs(self.ffts) ** 2.0 + self.ffts /= np.max(self.ffts) + for i in range(len(self.ffts)): + s += '%f\n' % (self.ffts[i]) + s += 'e\n' + plots.append('"-" with lines') elif mode == 'fft' or mode == 'mixer': sum_pwr = 0.0 self.ffts = np.fft.fft(self.buf * np.blackman(BUFSZ)) / (0.42 * BUFSZ) @@ -296,6 +305,9 @@ class wrap_gp(object): arrow_pos = (self.center_freq - self.relative_freq) / 1e6 h+= 'set arrow from %f, graph 0 to %f, graph 1 nohead\n' % (arrow_pos, arrow_pos) h+= 'set title "Spectrum: tuned to %f Mhz" %s\n' % (arrow_pos, label_color) + elif mode == 'fftf': + h+= 'set yrange [-1:1.2]\n' + h+= 'set title "fftf"\n' elif mode == 'float': h+= background h+= 'set yrange [-2:2]\n' @@ -386,6 +398,29 @@ class constellation_sink_c(gr.sync_block): def kill(self): self.gnuplot.kill() +class fft_sink_f(gr.sync_block): + """ + """ + def __init__(self, debug = _def_debug): + gr.sync_block.__init__(self, + name="fft_sink_f", + in_sig=[np.float32], + out_sig=None) + self.debug = debug + self.gnuplot = wrap_gp() + self.skip = 0 + + def work(self, input_items, output_items): + self.skip += 1 + if self.skip >= 50: + self.skip = 0 + in0 = input_items[0] + self.gnuplot.plot(in0, FFT_BINS, mode='fftf') + return len(input_items[0]) + + def kill(self): + self.gnuplot.kill() + class fft_sink_c(gr.sync_block): """ """ diff --git a/op25/gr-op25_repeater/apps/multi_rx.py b/op25/gr-op25_repeater/apps/multi_rx.py index e4c71ca..1969cd6 100755 --- a/op25/gr-op25_repeater/apps/multi_rx.py +++ b/op25/gr-op25_repeater/apps/multi_rx.py @@ -90,7 +90,9 @@ class device(object): self.tb = tb self.frequency = 0 - if config['args'].startswith('audio:'): + if config['args'].startswith('audio-if:'): + self.init_audio_if(config) + elif config['args'].startswith('audio:'): self.init_audio(config) elif config['args'].startswith('file:'): self.init_file(config) @@ -108,6 +110,17 @@ class device(object): self.frequency = config['frequency'] self.offset = config['offset'] + def init_audio_if(self, config): + filename = config['args'].replace('audio-if:', '') + self.audio_source = audio.source(config['rate'], filename) + self.null_source = blocks.null_source (gr.sizeof_float) + self.audio_cvt = blocks.float_to_complex() + self.tb.connect(self.audio_source, (self.audio_cvt, 0)) + self.tb.connect(self.null_source, (self.audio_cvt, 1)) + self.src = self.audio_cvt + self.frequency = config['frequency'] + self.offset = config['offset'] + def init_audio(self, config): filename = config['args'].replace('audio:', '') src = audio.source(self.sample_rate, filename) @@ -208,7 +221,8 @@ class channel(object): relative_freq = dev.frequency + dev.offset - config['frequency'], offset = dev.offset, if_rate = config['if_rate'], - symbol_rate = self.symbol_rate) + symbol_rate = self.symbol_rate, + use_old_decim = True if self.device.args.startswith('audio-if') else False) if msgq is not None: q = msgq else: diff --git a/op25/gr-op25_repeater/apps/p25_demodulator.py b/op25/gr-op25_repeater/apps/p25_demodulator.py index 65bcd7d..8c6fdcc 100644 --- a/op25/gr-op25_repeater/apps/p25_demodulator.py +++ b/op25/gr-op25_repeater/apps/p25_demodulator.py @@ -98,6 +98,7 @@ class p25_demod_base(gr.hier_block2): if ntaps & 1 == 0: ntaps += 1 coeffs = filter.firdes.root_raised_cosine(1.0, if_rate, symbol_rate, excess_bw, ntaps) + coeffs = [x*1.5 for x in coeffs] if filter_type == 'nxdn': coeffs = op25_c4fm_mod.c4fm_taps(sample_rate=self.if_rate, span=9, generator=op25_c4fm_mod.transfer_function_nxdn, symbol_rate=self.symbol_rate).generate() gain_adj = 1.8 # for nxdn48 6.25 KHz @@ -221,7 +222,8 @@ class p25_demod_cb(p25_demod_base): if_rate = _def_if_rate, gain_mu = _def_gain_mu, costas_alpha = _def_costas_alpha, - symbol_rate = _def_symbol_rate): + symbol_rate = _def_symbol_rate, + use_old_decim = False): """ Hierarchical block for P25 demodulation. @@ -252,7 +254,10 @@ class p25_demod_cb(p25_demod_base): self.set_baseband_gain(0.61) self.mixer = blocks.multiply_cc() - decimator_values = get_decim(input_rate) + if use_old_decim: + decimator_values = None # disable two stage decimator + else: + decimator_values = get_decim(input_rate) if decimator_values: self.decim, self.decim2 = decimator_values self.if1 = input_rate / self.decim diff --git a/op25/gr-op25_repeater/apps/rx.py b/op25/gr-op25_repeater/apps/rx.py index c671120..34fcc04 100755 --- a/op25/gr-op25_repeater/apps/rx.py +++ b/op25/gr-op25_repeater/apps/rx.py @@ -273,7 +273,7 @@ class p25_rx_block (gr.top_block): else: # complex input # local osc self.lo_freq = self.options.offset - if self.options.audio_if or self.options.ifile or self.options.input: + if self.options.ifile or self.options.input: self.lo_freq += self.options.calibration self.demod = p25_demodulator.p25_demod_cb( input_rate = capture_rate, demod_type = self.options.demod_type, @@ -283,7 +283,8 @@ class p25_rx_block (gr.top_block): gain_mu = self.options.gain_mu, costas_alpha = self.options.costas_alpha, excess_bw = self.options.excess_bw, - symbol_rate = self.symbol_rate) + symbol_rate = self.symbol_rate, + use_old_decim = True if self.options.audio_if else False) num_ambe = 0 if self.options.phase2_tdma: @@ -639,13 +640,17 @@ class p25_rx_block (gr.top_block): "source-dev": "AUDIO", "source-decim": 1 } self.audio_source = audio.source(capture_rate, audio_input_filename) + self.null_source = blocks.null_source (gr.sizeof_float) self.audio_cvt = blocks.float_to_complex() - self.connect((self.audio_source, 0), (self.audio_cvt, 0)) - self.connect((self.audio_source, 1), (self.audio_cvt, 1)) + self.connect(self.audio_source, (self.audio_cvt, 0)) + self.connect(self.null_source, (self.audio_cvt, 1)) self.source = blocks.multiply_const_cc(gain) self.connect(self.audio_cvt, self.source) self.__set_rx_from_audio(capture_rate) + rc = self.demod.set_relative_frequency(self.options.calibration) + sys.stderr.write('open_audio_c: set_relative_frequency %d: %s\n' % (self.options.calibration, rc)) + def open_audio(self, capture_rate, gain, audio_input_filename): self.info = { "capture-rate": capture_rate,