From dc2059f448353cf159179f13caf5dfb5cd0dcb17 Mon Sep 17 00:00:00 2001 From: csrichter Date: Thu, 1 Dec 2016 00:19:42 +0100 Subject: [PATCH] max freq block test, rt+ item_toggle_bit clears data --- grc/CMakeLists.txt | 3 +- grc/crfa_max_freq.xml | 51 +++++++++++++++ grc/rds_decoder.xml | 45 ------------- python/CMakeLists.txt | 3 +- python/__init__.py | 1 + python/max_freq.py | 119 ++++++++++++++++++++++++++++++++++ python/qtguitest.py | 35 +++++++++- python/rds_parser_table_qt.py | 28 ++++++-- 8 files changed, 232 insertions(+), 53 deletions(-) create mode 100644 grc/crfa_max_freq.xml delete mode 100644 grc/rds_decoder.xml create mode 100644 python/max_freq.py diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index c635b93..4221eea 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -21,5 +21,6 @@ install(FILES crfa_qtguitest.xml crfa_rds_table_qt.xml crfa_rds_parser_table_qt.xml - crfa_rds_decoder.xml DESTINATION share/gnuradio/grc/blocks + crfa_rds_decoder.xml + crfa_max_freq.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/crfa_max_freq.xml b/grc/crfa_max_freq.xml new file mode 100644 index 0000000..ccdc004 --- /dev/null +++ b/grc/crfa_max_freq.xml @@ -0,0 +1,51 @@ + + + max_freq + crfa_max_freq + [crfa] + import crfa + crfa.max_freq($fft_len, $num_decoders, $center_freq, $samp_rate) + + + fft_len + fft_len + int + + + num_decoders + num_decoders + int + + + center_freq + center_freq + float + + + samp_rate + samp_rate + int + + + + + + in + float + $fft_len + + + out + message + 1 + + + diff --git a/grc/rds_decoder.xml b/grc/rds_decoder.xml deleted file mode 100644 index 3d6384b..0000000 --- a/grc/rds_decoder.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - RDS Decoder (cr) - gr_rds_decoder_cr - [RDS] - import rds - rds.decoder($log, $debug) - - Log - log - False - bool - - - - - Debug - debug - False - bool - - - - - in - byte - - - out - message - 1 - - diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index cea59ec..9bcc146 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -34,7 +34,8 @@ GR_PYTHON_INSTALL( multi_rds_printer.py qtguitest.py rds_table_qt.py - rds_parser_table_qt.py DESTINATION ${GR_PYTHON_DIR}/crfa + rds_parser_table_qt.py + max_freq.py DESTINATION ${GR_PYTHON_DIR}/crfa ) ######################################################################## diff --git a/python/__init__.py b/python/__init__.py index 3cff438..9af8807 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -35,4 +35,5 @@ from multi_rds_printer import multi_rds_printer from qtguitest import qtguitest from rds_table_qt import rds_table_qt from rds_parser_table_qt import rds_parser_table_qt +from max_freq import max_freq # diff --git a/python/max_freq.py b/python/max_freq.py new file mode 100644 index 0000000..be79306 --- /dev/null +++ b/python/max_freq.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2016 <+YOU OR YOUR COMPANY+>. +# +# This is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this software; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import numpy as np +from gnuradio import gr +import code + +class max_freq(gr.sync_block): + """ + docstring for block max_freq + """ + def __init__(self, fft_len=1024,num_decoders=4,center_freq=0,samp_rate=0): + gr.sync_block.__init__(self, + name="max_freq", + in_sig=[(np.float32,fft_len)], + out_sig=None) + self.fft_len=fft_len + self.num_decoders=num_decoders + self.center_freq=center_freq + self.samp_rate=samp_rate + self.num_averages=5 + self.avg_counter=-1 + self.numbers_avg=[] + + + def work(self, input_items, output_items): + #in0 = input_items[0] + #ii=input_items + numbers=abs(input_items[0][0]) + threshold=6 + if self.avg_counter == -1: #init + self.numbers_avg=numbers + self.avg_counter=0 + elif self.avg_counter <= self.num_averages: + #np.mean( np.array([ old_set, new_set ]), axis=0 ) + self.numbers_avg=np.mean( np.array([ self.numbers_avg, numbers ]), axis=0 ) + self.avg_counter+=1 + elif len(np.where(self.numbers_avg>threshold)[0]) >0: + self.avg_counter=0 + numbers=self.numbers_avg + min_consec_max_threshold=4#minimum number of consecutive maximums (in fft domain) to consider signal as station + #TODO: what if no numbers over threshold? + #TODO auto threshold + #max_indices=[[421, 428, 429, 430, 431, 432, 433, 434, 436, 437, 438, 831, 832, 837, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851,852, 853, 854, 855, 856, 857]] + max_indices=np.where(numbers>threshold) + station_indices=[] + + last_index=max_indices[0][0] + #last_index=0 + count=1#counts number of consecutive maximums + threshold_reached=False + fuzzyness=10 +# max_indices[0].append(0)#to detect last station + max_indices=np.append(max_indices,0)#to detect last station + for i in max_indices: + if abs(i-last_index) <= fuzzyness: + count+=i-last_index + else:#last streak ended + if(threshold_reached): + station_indices.append(last_index-int(count/2))#use center of max-streak + threshold_reached=False + count=1 + else:#last streak didn't reach threshold -> no station + count=1 + if count==min_consec_max_threshold: + threshold_reached=True + last_index=i + + station_freqs=[] + #index to freq: + for index in station_indices: + startfreq=self.center_freq-self.samp_rate/2 + freq=self.samp_rate*index/self.fft_len+startfreq + station_freqs.append(freq) + + """ +[422 423 426 427 428 430 431 432 433 434 435 436 437 836 837 838 842 843 + 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 861 862 + 0] +[] +[] +[423 424 425 426 427 428 429 430 431 432 433 434 842 843 844 845 848 849 + 850 851 852 853 854 855 858 859 860 0] +[428, 851] +[101303125.0, 102294531.0] +[415 416 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 + 844 845 846 847 848 849 850 851 852 853 854 855 856 861 862 863 0] +[853] +[102299218.0] +""" + #f=open("/tmp/obj","r") + #import pickle + #pickle.load(ii,f) + #(array([431, 433, 437, 439, 849, 854, 856, 858, 861, 862]),) + #code.interact(local=locals()) + # <+signal processing here+> + print(max_indices) + print(station_indices) + print(station_freqs) + return len(input_items[0]) + diff --git a/python/qtguitest.py b/python/qtguitest.py index 98955c0..efcfae8 100644 --- a/python/qtguitest.py +++ b/python/qtguitest.py @@ -99,7 +99,28 @@ class CRWidget(QtGui.QWidget): layout.addWidget(self.table) self.table.setHorizontalHeaderLabels(horHeaders) + self.table.setMaximumHeight(250)#TODO use dynamic value + test=""" + adkasldjkasd + #ad + asd + as + d + asd + asdas + d + as + f + as + fa + + sfasfasfasfasofsa + afasfasf + """ self.tmc_message_label=QtGui.QLabel("TMC messages:") + #self.tmc_message_label.setTextInteractionFlags(QtCore.Qt.TextSelectableByKeyboard|QtCore.Qt.TextSelectableByMouse) + #self.tmc_message_label.setMaximumHeight(100) + self.event_filter=QtGui.QLineEdit()#QPlainTextEdit ? self.location_filter=QtGui.QLineEdit() @@ -113,10 +134,20 @@ class CRWidget(QtGui.QWidget): filter_layout.addWidget(QtGui.QLabel("location filter:")) filter_layout.addWidget(self.location_filter) #self.filter_label.setLayout(filter_layout) - + self.tmc_message_label.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) + #self.tmc_message_label.setTextInteractionFlags(QtCore.Qt.NoTextInteraction) layout.addLayout(filter_layout) layout.addWidget(self.tmc_message_label) - + + self.logOutput = Qt.QTextEdit(test) + self.logOutput.setReadOnly(True) + self.logOutput.setLineWrapMode(Qt.QTextEdit.NoWrap) + self.logOutput.setMaximumHeight(100) + font = self.logOutput.font() + font.setFamily("Courier") + font.setPointSize(10) + layout.addWidget(self.logOutput) + def display_data(self, event): diff --git a/python/rds_parser_table_qt.py b/python/rds_parser_table_qt.py index f38f373..4addc70 100644 --- a/python/rds_parser_table_qt.py +++ b/python/rds_parser_table_qt.py @@ -102,6 +102,7 @@ class rds_parser_table_qt(gr.sync_block): self.RDS_data[PI]["PSN_valid"]=[False]*8 self.RDS_data[PI]["AF"]={} self.RDS_data[PI]["DI"]=[2,2,2,2] + self.RDS_data[PI]["last_item_toggle_bit"]=2 print("found station %s"%PI) self.RDS_data[PI]["blockcounts"]["any"]+=1 if self.RDS_data[PI]["blockcounts"]["any"]==5: @@ -285,7 +286,8 @@ class rds_parser_table_qt(gr.sync_block): if not self.TMC_data.has_key(tmc_hash):#if message new message_string="TMC-message,event:%s location:%i,reflocs:%s, station:%s"%(event_name,tmc_location,self.ref_locs(tmc_location,""),self.RDS_data[PI]["PSN"]) self.TMC_data[tmc_hash]={"PI":PI,"string":message_string} - print(message_string) + self.signals.DataUpdateEvent.emit({'TMC_log':message_string}) + #print(message_string) except KeyError: #print("location '%i' not found"%tmc_location) pass @@ -330,12 +332,16 @@ class rds_parser_table_qt(gr.sync_block): rt=self.RDS_data[PI]["RT"] artist=rt[tag1_start:tag1_start+tag1_len+1] song=rt[tag2_start:tag2_start+tag2_len+1] - formatted_text="%s by %s"%(song,artist) + formatted_text="%s by %s %i"%(song,artist,item_running_bit) rtcol=self.colorder.index('text') self.signals.DataUpdateEvent.emit({'col':rtcol,'row':port,'PI':PI,'tooltip':formatted_text}) #self.signals.DataUpdateEvent.emit({'col':8,'row':port,'PI':PI,'string':formatted_text}) elif(not tag1_type=="ITEM.ARTIST" and not tag1_type=="DUMMY_CLASS"): - print("%s:RT+: tag1_type:%s, tag2_type:%s"%(PI,tag1_type,tag2_type)) + print("%s:RT+: tag1_type:%s, tag2_type:%s"%(PI,tag1_type,tag2_type)) + if not self.RDS_data[PI]["last_item_toggle_bit"] == item_toggle_bit: #new item + self.RDS_data[PI]["last_item_toggle_bit"] = item_toggle_bit + rtcol=self.colorder.index('text') + self.signals.DataUpdateEvent.emit({'col':rtcol,'row':port,'PI':PI,'tooltip':""}) else:#other group printdelay=50 self.printcounter+=1 @@ -450,7 +456,11 @@ class rds_parser_table_qt_Widget(QtGui.QWidget): layout.addWidget(self.table) self.table.setHorizontalHeaderLabels(horHeaders) + self.table.setMaximumHeight(250)#TODO use dynamic value + self.tmc_message_label=QtGui.QLabel("TMC messages:") + + self.event_filter=QtGui.QLineEdit()#QPlainTextEdit ? self.location_filter=QtGui.QLineEdit() @@ -465,11 +475,20 @@ class rds_parser_table_qt_Widget(QtGui.QWidget): layout.addLayout(filter_layout) layout.addWidget(self.tmc_message_label) - + self.logOutput = Qt.QTextEdit() + self.logOutput.setReadOnly(True) + self.logOutput.setLineWrapMode(Qt.QTextEdit.NoWrap) + #self.logOutput.setMaximumHeight(100) + font = self.logOutput.font() + font.setFamily("Courier") + font.setPointSize(10) + layout.addWidget(self.logOutput) def display_data(self, event): #pp.pprint(event) + if type(event)==dict and event.has_key('TMC_log'): + self.logOutput.append(Qt.QString.fromUtf8(event['TMC_log'])) if type(event)==dict and event.has_key('row'): if event.has_key('wrong_blocks'): item=self.table.cellWidget(event['row'],self.colorder.index('quality')) @@ -508,6 +527,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget): self.table.resizeColumnsToContents() def onCLick(self): print("button clicked") + code.interact(local=locals()) #self.reset_color() #pp.pprint(event) if __name__ == "__main__":