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__":