diff --git a/lib/rds_decoder_impl.cc b/lib/rds_decoder_impl.cc
index cfec273..ee51394 100644
--- a/lib/rds_decoder_impl.cc
+++ b/lib/rds_decoder_impl.cc
@@ -64,11 +64,21 @@ namespace gr {
////////////////////////// HELPER FUNTIONS /////////////////////////
void rds_decoder_impl::enter_no_sync() {
+ pmt::pmt_t data(pmt::PMT_F);
+ //pmt::pmt_t meta(pmt::PMT_NIL);
+ pmt::pmt_t meta(pmt::from_long(1));
+ pmt::pmt_t pdu(pmt::cons(meta, data)); // make PDU: (metadata, data) pair
+ message_port_pub(pmt::mp("out"), pdu);
presync = false;
d_state = NO_SYNC;
}
void rds_decoder_impl::enter_sync(unsigned int sync_block_number) {
+ pmt::pmt_t data(pmt::PMT_T);
+ //pmt::pmt_t meta(pmt::PMT_NIL);
+ pmt::pmt_t meta(pmt::from_long(1));
+ pmt::pmt_t pdu(pmt::cons(meta, data)); // make PDU: (metadata, data) pair
+ message_port_pub(pmt::mp("out"), pdu);
last_wrong_blocks_counter = 0;
wrong_blocks_counter = 0;
blocks_counter = 0;
@@ -119,8 +129,8 @@ void rds_decoder_impl::decode_group(unsigned int *group) {
bytes[11] = offset_chars[3];
bytes[12]=last_wrong_blocks_counter;
pmt::pmt_t data(pmt::make_blob(bytes, 13));
- pmt::pmt_t meta(pmt::PMT_NIL);
-
+ //pmt::pmt_t meta(pmt::PMT_NIL);
+ pmt::pmt_t meta(pmt::from_long(0));
pmt::pmt_t pdu(pmt::cons(meta, data)); // make PDU: (metadata, data) pair
message_port_pub(pmt::mp("out"), pdu);
}
diff --git a/python/cache/data7/0/3loioqhp.d b/python/cache/data7/0/3loioqhp.d
new file mode 100644
index 0000000..29be29c
Binary files /dev/null and b/python/cache/data7/0/3loioqhp.d differ
diff --git a/python/cache/data7/3/2jayz5n3.d b/python/cache/data7/3/2jayz5n3.d
new file mode 100644
index 0000000..2b536ce
Binary files /dev/null and b/python/cache/data7/3/2jayz5n3.d differ
diff --git a/python/cache/data7/5/2yrvdig5.d b/python/cache/data7/5/2yrvdig5.d
new file mode 100644
index 0000000..939b825
Binary files /dev/null and b/python/cache/data7/5/2yrvdig5.d differ
diff --git a/python/cache/data7/5/3k87jkxu.d b/python/cache/data7/5/3k87jkxu.d
new file mode 100644
index 0000000..37c61ed
Binary files /dev/null and b/python/cache/data7/5/3k87jkxu.d differ
diff --git a/python/cache/data7/6/2h60aaa6.d b/python/cache/data7/6/2h60aaa6.d
new file mode 100644
index 0000000..f3dc20e
Binary files /dev/null and b/python/cache/data7/6/2h60aaa6.d differ
diff --git a/python/cache/data7/6/3kqqka76.d b/python/cache/data7/6/3kqqka76.d
new file mode 100644
index 0000000..07c02be
Binary files /dev/null and b/python/cache/data7/6/3kqqka76.d differ
diff --git a/python/cache/data7/7/388lt1tw.d b/python/cache/data7/7/388lt1tw.d
new file mode 100644
index 0000000..1ed0a5e
Binary files /dev/null and b/python/cache/data7/7/388lt1tw.d differ
diff --git a/python/cache/data7/9/28slll29.d b/python/cache/data7/9/28slll29.d
new file mode 100644
index 0000000..453f040
Binary files /dev/null and b/python/cache/data7/9/28slll29.d differ
diff --git a/python/cache/data7/9/34vyu839.d b/python/cache/data7/9/34vyu839.d
new file mode 100644
index 0000000..b709433
Binary files /dev/null and b/python/cache/data7/9/34vyu839.d differ
diff --git a/python/cache/data7/9/3hmw9s8i.d b/python/cache/data7/9/3hmw9s8i.d
new file mode 100644
index 0000000..782707e
Binary files /dev/null and b/python/cache/data7/9/3hmw9s8i.d differ
diff --git a/python/cache/data7/a/32on7s1j.d b/python/cache/data7/a/32on7s1j.d
new file mode 100644
index 0000000..d6704e8
Binary files /dev/null and b/python/cache/data7/a/32on7s1j.d differ
diff --git a/python/cache/data7/a/3e289n0j.d b/python/cache/data7/a/3e289n0j.d
new file mode 100644
index 0000000..caac23d
Binary files /dev/null and b/python/cache/data7/a/3e289n0j.d differ
diff --git a/python/cache/data7/b/2y312ork.d b/python/cache/data7/b/2y312ork.d
new file mode 100644
index 0000000..59fc90b
Binary files /dev/null and b/python/cache/data7/b/2y312ork.d differ
diff --git a/python/rds_parser_table_qt.py b/python/rds_parser_table_qt.py
index c0450ab..11c71d9 100644
--- a/python/rds_parser_table_qt.py
+++ b/python/rds_parser_table_qt.py
@@ -746,7 +746,7 @@ class rds_parser_table_qt(gr.sync_block):#START
self.message_port_register_in(pmt.intern('in'))
self.set_msg_handler(pmt.intern('in'), functools.partial(self.handle_msg, port=0))
else:
- for i in range(0,nPorts):
+ for i in range(nPorts):
self.message_port_register_in(pmt.intern('in%d'%i))
self.set_msg_handler(pmt.intern('in%d'%i), functools.partial(self.handle_msg, port=i))
self.nPorts=nPorts
@@ -765,6 +765,10 @@ class rds_parser_table_qt(gr.sync_block):#START
self.TMC_data={}
self.IH_data={}
self.decoder_frequencies={}
+ self.decoders=[]
+ for i in range(nPorts):
+ self.decoders.append({'synced':False,'freq':None})
+ #self.decoder_synced={}
#self.colorder=['ID','freq','name','PTY','AF','time','text','quality','buttons']
self.colorder=['ID','freq','name','buttons','PTY','AF','time','text','quality','RT+']
self.workdir=workdir
@@ -840,6 +844,7 @@ class rds_parser_table_qt(gr.sync_block):#START
self.pty_dict=dict((int(rows[0]),rows[1]) for rows in reader)
f.close()
self.minute_count=0
+ self.minute_count_max=0
self.minute_count_timer=time.time()
self.save_data_timer=time.time()
@@ -857,14 +862,25 @@ class rds_parser_table_qt(gr.sync_block):#START
markerstring+='\n document.getElementById("errorid").innerHTML = "loaded "+markers.length+" markers";'
f.write(markerstring)
f.close()
+ def update_freq(self):
+ # " " is a tab character
+ message_string="decoder frequencies:"
+ for num in self.decoder_frequencies:
+ freq=self.decoder_frequencies[num]
+ if self.decoders[num]['synced']:
+ message_string+=" %i:%0.1fM"% (num,freq/1e6)
+ #print("'color:green'>%i:%0.1fM"% (num,freq/1e6))
+ else:#elif self.decoders[num]['synced']==False:
+ #print("'color:red'>%i:%0.1fM"% (num,freq/1e6))
+ message_string+=" %i:%0.1fM"% (num,freq/1e6)
+ message_string+=" tuned frequency:%0.1fM"%(self.tuning_frequency/1e6)
+ self.signals.DataUpdateEvent.emit({'decoder_frequencies':message_string})
+ #print(message_string)
+ #self.signals.DataUpdateEvent.emit({'row':decoder_num,'freq':freq_str})
+ #print("nr:%i freq:%s"%(tgtnum,freq_str))
def set_freq_tune(self,freq):
self.tuning_frequency=int(freq)
- message_string="decoder frequencies:"
- for num in self.decoder_frequencies:
- freq=self.decoder_frequencies[num]
- message_string+="\t %i:%0.1fM"% (num,freq/1e6)
- message_string+="\t tuned frequency:%0.1fM"%(self.tuning_frequency/1e6)
- self.signals.DataUpdateEvent.emit({'decoder_frequencies':message_string})
+ self.update_freq()
def set_freq(self,msg):
m = pmt.symbol_to_string(msg)
decoder_num=int(m.split()[0])-1#msgs are 1-indexed, decoder_num is 0-indexed
@@ -875,14 +891,7 @@ class rds_parser_table_qt(gr.sync_block):#START
freq_str="%i:%0.1fM"% (decoder_num,freq/1e6)
except ValueError:
pass#leave string as is
- message_string="decoder frequencies:"
- for num in self.decoder_frequencies:
- freq=self.decoder_frequencies[num]
- message_string+="\t %i:%0.1fM"% (num,freq/1e6)
- message_string+="\t tuned frequency:%0.1fM"%(self.tuning_frequency/1e6)
- self.signals.DataUpdateEvent.emit({'decoder_frequencies':message_string})
- #self.signals.DataUpdateEvent.emit({'row':decoder_num,'freq':freq_str})
- #print("nr:%i freq:%s"%(tgtnum,freq_str))
+ self.update_freq()
def init_data_for_PI(self,PI):
self.RDS_data[PI]={}
#self.RDS_data[PI]["blockcounts"]={}# no defaults (works aswell)
@@ -900,21 +909,30 @@ class rds_parser_table_qt(gr.sync_block):#START
self.RDS_data[PI]["internals"]={"last_rt_tooltip":"","unfinished_TMC":{},"last_valid_rt":"","last_valid_psn":"","RT_history":[]}
self.RDS_data[PI]["time"]={"timestring":"88:88","datestring":"00-00-0000","datetime":None}
def handle_msg(self, msg, port):#port from 0 to 3
+ if pmt.to_long(pmt.car(msg))==1L:
+ data=pmt.to_python(pmt.cdr(msg))
+ #print("port:%i, data: %s"%(port,data))
+ self.decoders[port]['synced']=data
+ self.update_freq()
+ else: #elif pmt.to_long(pmt.car(msg))==0L
+ array=pmt.to_python(msg)[1]
+
if time.time()-self.save_data_timer > 10:#every 10 seconds
self.save_data_timer=time.time()
self.clean_data_and_commit_db()
if time.time()-self.minute_count_timer > 3:#every 3 second
+ self.minute_count_max=self.minute_count
self.minute_count=0
self.minute_count_timer=time.time()
pr.enable()#disabled-internal-profiling
self.minute_count+=1
- self.signals.DataUpdateEvent.emit({'group_count':self.minute_count})
+ self.signals.DataUpdateEvent.emit({'group_count':self.minute_count,'group_count_max':self.minute_count_max})
if self.writeDB:
#db=sqlite3.connect(self.db_name)
db=self.db
- array=pmt.to_python(msg)[1]
+
groupNR=array[2]&0b11110000
groupVar=array[2]&0b00001000
if (groupVar == 0):
@@ -1133,23 +1151,29 @@ class rds_parser_table_qt(gr.sync_block):#START
ESW_channel_identification=SLC
#end of 1A decode
elif (groupType == "2A"):#RT radiotext
- if(not self.RDS_data[PI].has_key("RT")):#initialize variables
- self.RDS_data[PI]["RT"]="_"*64
- self.RDS_data[PI]["RT_valid"]=[False]*64
- self.RDS_data[PI]["RT_all_valid"]=False
+ if(not self.RDS_data[PI].has_key("RT_0")):#initialize variables
+ self.RDS_data[PI]["RT_0"]={"RT":"_"*64,"RT_valid":[False]*64,"RT_all_valid":False}
+ self.RDS_data[PI]["RT_1"]={"RT":"_"*64,"RT_valid":[False]*64,"RT_all_valid":False}
+ #self.RDS_data[PI]["RT"]="_"*64
+ #self.RDS_data[PI]["RT_valid"]=[False]*64
+ #self.RDS_data[PI]["RT_all_valid"]=False
self.RDS_data[PI]["RT_last_ab_flag"]=2
adr= array[3]&0b00001111
ab_flag=(array[3]&0b00010000)>>4
#print("PI:%s, AB:%i"%(PI,ab_flag))
- if self.RDS_data[PI]["RT_last_ab_flag"] !=ab_flag:#AB flag changed -> clear text
- self.RDS_data[PI]["RT"]="_"*64
- self.RDS_data[PI]["RT_valid"]=[False]*64
- self.RDS_data[PI]["RT_last_ab_flag"] =ab_flag
+
+
+ #if self.RDS_data[PI]["RT_last_ab_flag"] !=ab_flag:#AB flag changed -> clear text
+ # self.RDS_data[PI]["RT"]="_"*64
+ # self.RDS_data[PI]["RT_valid"]=[False]*64
+ # self.RDS_data[PI]["RT_last_ab_flag"] =ab_flag
+ self.RDS_data[PI]["RT_last_ab_flag"] =ab_flag
+
segment=self.decode_chars(chr(array[4])+chr(array[5])+chr(array[6])+chr(array[7]))
#print("RT:adress: %d, segment:%s"%(adr,segment))
#self.signals.DataUpdateEvent.emit({'col':5,'row':port,'PI':PI,'groupType':groupType,'adress':adr,'segment':segment})
- text_list=list(self.RDS_data[PI]["RT"])
+ text_list=list(self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"])
#determine text length:
try:
text_end=text_list.index('\r')
@@ -1167,27 +1191,27 @@ class rds_parser_table_qt(gr.sync_block):#START
text_list=['_']*64 #clear text
text_list[adr*4:adr*4+4]=segment
#reset stored text:
- self.RDS_data[PI]["RT"]="_"*64
- self.RDS_data[PI]["RT_valid"]=[False]*64
+ self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"]="_"*64
+ self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_valid"]=[False]*64
#predict RT from last texts:
for rt in self.RDS_data[PI]["internals"]["RT_history"]:
if rt[adr*4:adr*4+4]==list(segment):
- self.RDS_data[PI]["RT"]="".join(rt)
+ self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"]="".join(rt)
predicted=True
- self.RDS_data[PI]["RT_valid"][adr*4:adr*4+4]=[True] *4
+ self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_valid"][adr*4:adr*4+4]=[True] *4
if not predicted:
- self.RDS_data[PI]["RT"]="".join(text_list)
+ self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"]="".join(text_list)
#determine if (new) text is valid
- self.RDS_data[PI]["RT_all_valid"]=True
+ self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_all_valid"]=True
for i in range(0,text_end):
- if (not self.RDS_data[PI]["RT_valid"][i]):
- self.RDS_data[PI]["RT_all_valid"] = False
- if(self.RDS_data[PI]["RT_all_valid"]):
+ if (not self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_valid"][i]):
+ self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_all_valid"] = False
+ if(self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_all_valid"]):
#textcolor="black"
textcolor=""#use default color (white if background is black)
- l=list(self.RDS_data[PI]["RT"])
+ l=list(self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"])
rt="".join(l[0:text_end])#remove underscores(default symbol) after line end marker
if not self.RDS_data[PI]["internals"]["last_valid_rt"]==rt:#ignore duplicates
self.RDS_data[PI]["internals"]["RT_history"].append(l)
@@ -1205,7 +1229,7 @@ class rds_parser_table_qt(gr.sync_block):#START
pass#no rt+ -> dont save
else:
textcolor="gray"
- formatted_text=self.color_text(self.RDS_data[PI]["RT"],adr*4,adr*4+4,textcolor,segmentcolor)
+ formatted_text=self.color_text(self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"],adr*4,adr*4+4,textcolor,segmentcolor)
rtcol=self.colorder.index('text')
self.signals.DataUpdateEvent.emit({'col':rtcol,'row':port,'PI':PI,'string':formatted_text})
@@ -1394,9 +1418,10 @@ class rds_parser_table_qt(gr.sync_block):#START
if self.debug:
print("toggle bit changed on PI:%s, cleared RT-tt"%PI)
self.signals.DataUpdateEvent.emit({'col':rtcol,'row':port,'PI':PI,'tooltip':""})
- if self.RDS_data[PI].has_key("RT"):
- rt=self.RDS_data[PI]["RT"]
- rt_valid=self.RDS_data[PI]["RT_valid"]
+ if self.RDS_data[PI].has_key("RT_0"):
+ ab_flag=self.RDS_data[PI]["RT_last_ab_flag"]
+ rt=self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"]
+ rt_valid=self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_valid"]
if not tag1_type=="DUMMY_CLASS" and all(rt_valid[tag1_start:tag1_start+tag1_len+1]):
self.RDS_data[PI]["RT+"][tag1_type]=rt[tag1_start:tag1_start+tag1_len+1]
self.RDS_data[PI]["internals"]["RT+_times"][tag1_type]=time.time()
@@ -1414,9 +1439,10 @@ class rds_parser_table_qt(gr.sync_block):#START
tags="ir:%i,it:%i"%(item_running_bit,item_toggle_bit)
rtpcol=self.colorder.index('RT+')
self.signals.DataUpdateEvent.emit({'col':rtpcol,'row':port,'PI':PI,'string':tags})
- if(tag2_type=="ITEM.TITLE" and self.RDS_data[PI].has_key("RT")):#TODO remove duplicate code
- rt=self.RDS_data[PI]["RT"]
- rt_valid=self.RDS_data[PI]["RT_valid"]
+ if(tag2_type=="ITEM.TITLE" and self.RDS_data[PI].has_key("RT_0")):#TODO remove duplicate code
+ ab_flag=self.RDS_data[PI]["RT_last_ab_flag"]
+ rt=self.RDS_data[PI]["RT_"+str(ab_flag)]["RT"]
+ rt_valid=self.RDS_data[PI]["RT_"+str(ab_flag)]["RT_valid"]
artist="?"
song="?"
if all(rt_valid[tag1_start:tag1_start+tag1_len+1]):
@@ -1662,12 +1688,12 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
layout.addWidget(self.table)
self.table.setHorizontalHeaderLabels(self.colorder)
#self.table.setMaximumHeight(300)#TODO use dynamic value
-
- button_layout = Qt.QHBoxLayout()
+
+ button_layout = Qt.QHBoxLayout()
codebutton = QtGui.QPushButton("code.interact")
codebutton.clicked.connect(self.onCLick)
button_layout.addWidget(codebutton)
- ih_button = QtGui.QPushButton("show IH data")
+ ih_button = QtGui.QPushButton("show IH data")
ih_button.clicked.connect(self.showIHdata)
button_layout.addWidget(ih_button)
save_button = QtGui.QPushButton("save")
@@ -1681,8 +1707,10 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
button_layout.addWidget(mode_button)
layout.addLayout(button_layout)
label_layout = Qt.QHBoxLayout()
- self.freq_label=QtGui.QLabel("decoder frequencies:")
- self.count_label=QtGui.QLabel("count:")
+ self.freq_label=QtGui.QLabel("decoder frequencies:")
+ #self.freq_label.setTextFormat(QtCore.Qt.RichText)
+ #self.freq_label.setTextFormat(QtCore.Qt.PlainText)
+ self.count_label=QtGui.QLabel("count:")
label_layout.addWidget(self.freq_label)
label_layout.addWidget(self.count_label)
layout.addLayout(label_layout)
@@ -1765,7 +1793,7 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
def display_data(self, event):
#pp.pprint(event)
if type(event)==dict and event.has_key('group_count'):
- self.count_label.setText("count:%i"%event['group_count'])
+ self.count_label.setText("count:%02i, max:%i"%(event['group_count'],event['group_count_max']))
if type(event)==dict and event.has_key('decoder_frequencies'):
self.freq_label.setText(event['decoder_frequencies'])
if type(event)==dict and event.has_key('TMC_log') and self.showTMC:
@@ -1776,17 +1804,6 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
if self.tableobj.tmc_messages.matchFilter(tmc_msg,filters):
self.logOutput.append(Qt.QString.fromUtf8(tmc_msg.log_string()))
self.logOutput.append(Qt.QString.fromUtf8(tmc_msg.multi_str()))
- #ef=unicode(self.event_filter.text().toUtf8(), encoding="UTF-8").lower()
- #lf=unicode(self.location_filter.text().toUtf8(), encoding="UTF-8").lower()
- #reflocs=tmc_msg.location.reflocs
- #reflocs_cmp=unicode(reflocs, encoding="UTF-8").lower()
- #event_cmp=unicode(str(tmc_msg.event), encoding="UTF-8").lower()
-
- #if not reflocs_cmp.find(lf)==-1 and not event_cmp.find(ef)==-1:
- #message_string=tmc_msg.log_string()
- #self.logOutput.append(Qt.QString.fromUtf8(message_string))
- #if event.has_key('multi_str'):
- #self.logOutput.append(Qt.QString.fromUtf8(event['multi_str']))
if type(event)==dict and event.has_key('TMC_log_str')and self.showTMC:
ef=unicode(self.event_filter.text().toUtf8(), encoding="UTF-8").lower()
lf=unicode(self.location_filter.text().toUtf8(), encoding="UTF-8").lower()
@@ -1873,11 +1890,9 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
freq=int(self.tableobj.RDS_data[PI]['AF']['main'])
#print("setaudio row:%i, chan:%s, PI:%s,freq:%i"%(row,audio_channel,PI,freq))
send_pmt = pmt.pmt_to_python.pmt_from_dict({"cmd":"set_audio_freq","chan":audio_channel,"freq":freq})
- #send_pmt = pmt.pmt_to_python.pmt_from_dict({"cmd":"set_audio_freq","chan":"left","freq":freq})
self.tableobj.message_port_pub(pmt.intern('ctrl'), send_pmt)
#catch:
#print("no freq, cant set decoder")#show notification? popup: too intrusive, log: maybe not visible, other possibility?
-
#print("freq not in RX BW")#automatically shift freq-tune?
def getDetails(self,row):
PIcol=self.colorder.index('ID')
@@ -1901,8 +1916,9 @@ class rds_parser_table_qt_Widget(QtGui.QWidget):
try:
del rds_data['blockcounts']
del rds_data['PSN_valid']
- del rds_data['RT_valid']
- del rds_data['RT_valid']
+ del rds_data["RT_0"]['RT_valid']
+ del rds_data["RT_1"]['RT_valid']
+ rds_data['internals']['RT_history']=["".join(rt) for rt in rds_data['internals']['RT_history']]#combine char lists into strings (more compact)
except KeyError:
pass
l=QtGui.QLabel("Data:%s"%pp.pformat(rds_data))