diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index eec0d11..e931ab7 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -28,5 +28,6 @@ install(FILES crfa_vector_cutter.xml crfa_decoder_compare.xml crfa_diff_add_sync_decim.xml - crfa_sync_decim.xml DESTINATION share/gnuradio/grc/blocks + crfa_sync_decim.xml + crfa_rds_decoder_redsea.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/crfa_rds_decoder_redsea.xml b/grc/crfa_rds_decoder_redsea.xml new file mode 100644 index 0000000..ddcd19d --- /dev/null +++ b/grc/crfa_rds_decoder_redsea.xml @@ -0,0 +1,45 @@ + + + RDS Decoder (redsea) + crfa_rds_decoder_redsea + [crfa] + import crfa + crfa.rds_decoder($log, $debug) + + Log + log + False + bool + + + + + Debug + debug + False + bool + + + + + in + byte + + + out + message + 1 + + diff --git a/include/crfa/CMakeLists.txt b/include/crfa/CMakeLists.txt index 80deb04..505fbbd 100644 --- a/include/crfa/CMakeLists.txt +++ b/include/crfa/CMakeLists.txt @@ -24,5 +24,6 @@ install(FILES api.h rds_decoder.h diff_add_sync_decim.h - sync_decim.h DESTINATION include/crfa + sync_decim.h + rds_decoder_redsea.h DESTINATION include/crfa ) diff --git a/include/crfa/rds_decoder_redsea.h b/include/crfa/rds_decoder_redsea.h new file mode 100644 index 0000000..05b52ab --- /dev/null +++ b/include/crfa/rds_decoder_redsea.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2017 <+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. + */ + + +#ifndef INCLUDED_CRFA_RDS_DECODER_REDSEA_H +#define INCLUDED_CRFA_RDS_DECODER_REDSEA_H + +#include +#include + +namespace gr { + namespace crfa { + + /*! + * \brief <+description of block+> + * \ingroup crfa + * + */ + class CRFA_API rds_decoder_redsea : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr sptr; + + /*! + * \brief Return a shared_ptr to a new instance of crfa::rds_decoder_redsea. + * + * To avoid accidental use of raw pointers, crfa::rds_decoder_redsea's + * constructor is in a private implementation + * class. crfa::rds_decoder_redsea::make is the public interface for + * creating new instances. + */ + static sptr make(bool log,bool debug); + }; + + } // namespace crfa +} // namespace gr + +#endif /* INCLUDED_CRFA_RDS_DECODER_REDSEA_H */ + diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 91f8e20..022c609 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -27,7 +27,8 @@ link_directories(${Boost_LIBRARY_DIRS}) list(APPEND crfa_sources rds_decoder_impl.cc diff_add_sync_decim_impl.cc - sync_decim_impl.cc ) + sync_decim_impl.cc + rds_decoder_redsea_impl.cc ) set(crfa_sources "${crfa_sources}" PARENT_SCOPE) if(NOT crfa_sources) diff --git a/lib/rds_decoder_impl.cc b/lib/rds_decoder_impl.cc index 259d287..650b9d7 100644 --- a/lib/rds_decoder_impl.cc +++ b/lib/rds_decoder_impl.cc @@ -28,6 +28,8 @@ #include #include "constants.h" #include "rds_decoder_impl.h" +#include +#include namespace gr { namespace crfa { @@ -260,7 +262,9 @@ int rds_decoder_impl::work (int noutput_items, bit_counter++; } return noutput_items; - }/*work function*/ + }/*end of work function*/ + + } /* namespace crfa */ } /* namespace gr */ diff --git a/lib/rds_decoder_impl.h b/lib/rds_decoder_impl.h index 2fa36a3..6270b57 100644 --- a/lib/rds_decoder_impl.h +++ b/lib/rds_decoder_impl.h @@ -60,6 +60,15 @@ private: unsigned char lastseen_offset; unsigned char block_number; enum { NO_SYNC, SYNC } d_state; + /*//below copied from redsea + enum eOffset { + OFFSET_A, OFFSET_B, OFFSET_C, OFFSET_CI, OFFSET_D, OFFSET_INVALID + } ; + uint32_t calcSyndrome(uint32_t vec); + eOffset offsetForSyndrome(uint16_t syndrome); + eOffset nextOffsetFor(eOffset o); + uint32_t correctBurstErrors(uint32_t block, eOffset offset);*/ + }; diff --git a/lib/rds_decoder_redsea_impl.cc b/lib/rds_decoder_redsea_impl.cc new file mode 100644 index 0000000..dca4a41 --- /dev/null +++ b/lib/rds_decoder_redsea_impl.cc @@ -0,0 +1,334 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define dout debug && std::cout +#define lout log && std::cout + +#include +#include "constants.h" +#include "rds_decoder_redsea_impl.h" +#include +#include + +namespace gr { + namespace crfa { + + rds_decoder_redsea::sptr + rds_decoder_redsea::make(bool log, bool debug) + { + return gnuradio::get_initial_sptr + (new rds_decoder_redsea_impl(log, debug)); + } + + /* + * The private constructor + */ + rds_decoder_redsea_impl::rds_decoder_redsea_impl(bool log, bool debug) + : gr::sync_block("rds_decoder_redsea", + gr::io_signature::make (1, 1, sizeof(char)), + gr::io_signature::make (0, 0, 0)), + log(log), + debug(debug) +{ + set_output_multiple(104); // 1 RDS datagroup = 104 bits + message_port_register_out(pmt::mp("out")); + enter_no_sync(); +} + + /* + * Our virtual destructor. + */ + rds_decoder_redsea_impl::~rds_decoder_redsea_impl() + { + } + +////////////////////////// HELPER FUNTIONS ///////////////////////// + +void rds_decoder_redsea_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_redsea_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; + block_bit_counter = 0; + block_number = (sync_block_number + 1) % 4; + group_assembly_started = false; + d_state = SYNC; +} + +/* see Annex B, page 64 of the standard */ +unsigned int rds_decoder_redsea_impl::calc_syndrome(unsigned long message, + unsigned char mlen) { + unsigned long reg = 0; + unsigned int i; + const unsigned long poly = 0x5B9; + const unsigned char plen = 10; + + for (i = mlen; i > 0; i--) { + reg = (reg << 1) | ((message >> (i-1)) & 0x01); + if (reg & (1 << plen)) reg = reg ^ poly; + } + for (i = plen; i > 0; i--) { + reg = reg << 1; + if (reg & (1<> 8U) & 0xffU; + bytes[1] = (group[0] ) & 0xffU; + bytes[2] = (group[1] >> 8U) & 0xffU; + bytes[3] = (group[1] ) & 0xffU; + bytes[4] = (group[2] >> 8U) & 0xffU; + bytes[5] = (group[2] ) & 0xffU; + bytes[6] = (group[3] >> 8U) & 0xffU; + bytes[7] = (group[3] ) & 0xffU; + + // RDS offset words + bytes[8] = offset_chars[0]; + bytes[9] = offset_chars[1]; + bytes[10] = offset_chars[2]; + 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::from_long(0)); + pmt::pmt_t pdu(pmt::cons(meta, data)); // make PDU: (metadata, data) pair + message_port_pub(pmt::mp("out"), pdu); +} +//work function +int rds_decoder_redsea_impl::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const bool *in = (const bool *) input_items[0]; + + dout << "RDS data decoder at work: input_items = " + << noutput_items << ", /104 = " + << noutput_items / 104 << std::endl; + + int i=0,j; + unsigned long bit_distance, block_distance; + unsigned int block_calculated_crc, block_received_crc, checkword,dataword; + unsigned int reg_syndrome; + unsigned char offset_char('x'); // x = error while decoding the word offset + +/* the synchronization process is described in Annex C, page 66 of the standard */ + while (i=offset_pos[j]) + block_distance=offset_pos[j]+4-offset_pos[lastseen_offset]; + else + block_distance=offset_pos[j]-offset_pos[lastseen_offset]; + if ((block_distance*26)!=bit_distance) presync=false; + else { + lout << "@@@@@ Sync State Detected" << std::endl; + enter_sync(j); + } + } + break; //syndrome found, no more cycles + } + } + break; + case SYNC: +/* wait until 26 bits enter the buffer */ + if (block_bit_counter<25) block_bit_counter++; + else { + /*uint32_t block = reg; + uint16_t message = block >> 10; + + received_offset_ = offsetForSyndrome(calcSyndrome(block)); + + if (!acquireSync()) + continue; + + block_counter_++; + bool was_valid_word = true; + + if (expected_offset_ == OFFSET_C && received_offset_ == OFFSET_CI) + expected_offset_ = OFFSET_CI; + + block_has_errors_[block_counter_ % block_has_errors_.size()] = false; + + if (received_offset_ != expected_offset_) { + block_has_errors_[block_counter_ % block_has_errors_.size()] = true; + + was_valid_word = false; + + // Detect & correct clock slips (Section C.1.2) + if (expected_offset_ == OFFSET_A && pi_ != 0 && + ((wideblock_ >> 12) & kBitmask16) == pi_) { + message = pi_; + wideblock_ >>= 1; + received_offset_ = OFFSET_A; + } else if (expected_offset_ == OFFSET_A && pi_ != 0 && + ((wideblock_ >> 10) & kBitmask16) == pi_) { + message = pi_; + wideblock_ = (wideblock_ << 1) + getNextBit(); + received_offset_ = OFFSET_A; + left_to_read_ = 25; + } else { + uint32_t corrected_block = correctBurstErrors(block, expected_offset_); + if (corrected_block != block) { + message = corrected_block >> 10; + received_offset_ = expected_offset_; + } + } + + // Still no valid syndrome + if (received_offset_ != expected_offset_) + uncorrectable(); + } + + // Error-free block received + + if (received_offset_ == expected_offset_) { + if (expected_offset_ == OFFSET_CI) + group.setCI(message); + else + group.set(block_number_for_offset[expected_offset_], message); + + if (group.hasPi()) + pi_ = group.pi(); + } + + expected_offset_ = nextOffsetFor(expected_offset_); + + if (expected_offset_ == OFFSET_A) { + break; + }*/ + good_block=false; + dataword=(reg>>10) & 0xffff;//data part of received block (upper 16 bits) + block_calculated_crc=calc_syndrome(dataword,16); + + checkword=reg & 0x3ff;//checkword part of received block (lower 10 bits) +/* manage special case of C or C' offset word */ + if (block_number==2) { + block_received_crc=checkword^offset_word[block_number]; + if (block_received_crc==block_calculated_crc) { + good_block=true; + offset_char = 'C'; + } else { + block_received_crc=checkword^offset_word[4]; + if (block_received_crc==block_calculated_crc) { + good_block=true; + offset_char = 'c'; // C' (C-Tag) + } else { + wrong_blocks_counter++; + good_block=false; + } + } + } + else { + block_received_crc=checkword^offset_word[block_number]; + if (block_received_crc==block_calculated_crc) { + good_block=true; + if (block_number==0) offset_char = 'A'; + else if (block_number==1) offset_char = 'B'; + else if (block_number==3) offset_char = 'D'; + } else { + wrong_blocks_counter++; + good_block=false; + } + } +/* done checking CRC */ + if (block_number==0 && good_block) { + group_assembly_started=true; + group_good_blocks_counter=1; + } + if (group_assembly_started) { + if (!good_block) group_assembly_started=false; + else { + group[block_number]=dataword; + offset_chars[block_number] = offset_char; + group_good_blocks_counter++; + } + if (group_good_blocks_counter==5) decode_group(group); + } + block_bit_counter=0; + block_number=(block_number+1) % 4; + blocks_counter++; +/* 1187.5 bps / 104 bits = 11.4 groups/sec, or 45.7 blocks/sec */ + if (blocks_counter==50) { + last_wrong_blocks_counter=wrong_blocks_counter; + if (wrong_blocks_counter>35) { + lout << "@@@@@ Lost Sync (Got " << wrong_blocks_counter + << " bad blocks on " << blocks_counter + << " total)" << std::endl; + enter_no_sync(); + } else { + lout << "@@@@@ Still Sync-ed (Got " << wrong_blocks_counter + << " bad blocks on " << blocks_counter + << " total)" << std::endl; + } + blocks_counter=0; + wrong_blocks_counter=0; + } + } + break; + default: + d_state=NO_SYNC; + break; + } + i++; + bit_counter++; + } + return noutput_items; + }/*end of work function*/ + + + } /* namespace crfa */ +} /* namespace gr */ + diff --git a/lib/rds_decoder_redsea_impl.h b/lib/rds_decoder_redsea_impl.h new file mode 100644 index 0000000..252f37f --- /dev/null +++ b/lib/rds_decoder_redsea_impl.h @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* + * 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. + */ + +#ifndef INCLUDED_CRFA_RDS_DECODER_IMPL_H +#define INCLUDED_CRFA_RDS_DECODER_IMPL_H + +#include + +namespace gr { + namespace crfa { + + class rds_decoder_redsea_impl : public rds_decoder_redsea + { +public: + rds_decoder_redsea_impl(bool log, bool debug); + +private: + ~rds_decoder_redsea_impl(); + + // Where all the action really happens + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + void enter_no_sync(); + void enter_sync(unsigned int); + unsigned int calc_syndrome(unsigned long, unsigned char); + void decode_group(unsigned int*); + + unsigned long bit_counter; + unsigned long lastseen_offset_counter, reg; + unsigned int block_bit_counter; + unsigned int wrong_blocks_counter; + unsigned int blocks_counter; + unsigned int group_good_blocks_counter; + unsigned int group[4]; + unsigned char offset_chars[4]; // [ABCcDEx] (x=error) + bool debug; + bool log; + bool presync; + bool good_block; + bool group_assembly_started; + unsigned char last_wrong_blocks_counter; + unsigned char lastseen_offset; + unsigned char block_number; + enum { NO_SYNC, SYNC } d_state; + //below copied from redsea + enum eOffset { + OFFSET_A, OFFSET_B, OFFSET_C, OFFSET_CI, OFFSET_D, OFFSET_INVALID + } ; + uint32_t calcSyndrome(uint32_t vec); + eOffset offsetForSyndrome(uint16_t syndrome); + eOffset nextOffsetFor(eOffset o); + uint32_t correctBurstErrors(uint32_t block, eOffset offset); + + + }; + + } // namespace crfa +} // namespace gr + +#endif /* INCLUDED_CRFA_RDS_DECODER_IMPL_H */ + diff --git a/python/rds_parser_table_qt.py b/python/rds_parser_table_qt.py index 74d7033..1f92c06 100644 --- a/python/rds_parser_table_qt.py +++ b/python/rds_parser_table_qt.py @@ -320,34 +320,39 @@ class tmc_dict: return retStr def getMarkerString(self): markerstring="" - for lcn in self.messages: - loc=None - endloc=None - map_tag='

' - for updateClass in self.messages[lcn]: - message=self.messages[lcn][updateClass] - if message.cancellation_time==None: - color="black" - else: - color="gray" - if message.location.has_koord: - if loc==None:#first message at this location - map_tag+='

' - map_tag+=message.location_text() - map_tag+='

' - if message.cancellation_time==None: - endloc=message.end_loc()#line displays length of 1st message (lowest class), that is not cancelled - loc=message.location - map_tag+='
'%color - map_tag+=message.map_string() - map_tag+='
' - map_tag+='
' - map_tag+='

' - if not loc==None: - if endloc==None or not endloc.is_valid: - endloc=loc#creates line of 0 length (dot) - markerstring+=tmc_dict.marker_template.format(loc=loc.koord_str_google,text=map_tag,endloc=endloc.koord_str_google) - markerstring+="\n" + try: + for lcn in self.messages: + loc=None + endloc=None + map_tag='

' + for updateClass in self.messages[lcn]: + message=self.messages[lcn][updateClass] + if message.cancellation_time==None: + color="black" + else: + color="gray" + if message.location.has_koord: + if loc==None:#first message at this location + map_tag+='

' + map_tag+=message.location_text() + map_tag+='

' + if message.cancellation_time==None: + endloc=message.end_loc()#line displays length of 1st message (lowest class), that is not cancelled + loc=message.location + map_tag+='
'%color + map_tag+=message.map_string() + map_tag+='
' + map_tag+='
' + map_tag+='

' + if not loc==None: + if endloc==None or not endloc.is_valid: + endloc=loc#creates line of 0 length (dot) + markerstring+=tmc_dict.marker_template.format(loc=loc.koord_str_google,text=map_tag,endloc=endloc.koord_str_google) + markerstring+="\n" + except UnicodeDecodeError as e: + print(e) + code.interact(local=locals()) + pass return markerstring @@ -445,11 +450,12 @@ class tmc_message: str_list=[str(elem) for elem in self.events] return str(", ".join(str_list)) def log_string(self): - return str(self.event.updateClass)+": "+self.getTime()+": "+self.location_text()+": "+self.events_string()+"; "+self.info_str()+"; "+self.psn + return str(self.event.updateClass)+": "+self.getTime()+": "+self.location_text()+": "+self.events_string()+"; "+self.info_str()+"; "+self.psn.encode("utf-8") + #2017-03-16 fix:self.psn.encode("utf-8"), utf8 decoding happens later def db_string(self): return str(self.location)+": "+str(self.event.updateClass)+": "+self.events_string()+"; "+self.info_str() def map_string(self): - return ''%self.multi_str()+str(self.event.updateClass)+": "+self.getTime()+": "+self.events_string()+self.info_str()+"; "+self.psn+"" + return ''%self.multi_str()+str(self.event.updateClass)+": "+self.getTime()+": "+self.events_string()+self.info_str()+"; "+self.psn.encode("utf-8")+"" def end_loc(self): return self.location.get_extent_location(self.location,self.tmc_extent,self.tmc_dir) def location_text(self): @@ -489,7 +495,8 @@ class tmc_message: #E #EventCode: EventText #F - return str(text) + #return unicode(text,encoding="utf-8") + return text def __str__(self): return str(self.event.updateClass)+": "+self.getTime()+": "+self.events_string()+"; "+self.multi_str() def __repr__(self): @@ -904,6 +911,22 @@ class rds_parser_table_qt(gr.sync_block):#START self.RDS_data[PI]={} #self.RDS_data[PI]["blockcounts"]={}# no defaults (works aswell) #defaults are to keep colors in piechart consistent between stations: + + coverage_area={"0":"local,","1":"international,","2":"national,","3":"supranational,"} + pi_str="" + if list(PI)[1] in "456789ABCDEF": + pi_str+="regional, " + else: + pi_str+=coverage_area[list(PI)[1]] + bundeslaender={"0":"Baden-Württemberg","1":"Bayern","2":"Berlin","3":"Brandenburg","4":"Bremen und Bremerhaven", + "5":"Hamburg","6":"Hessen","7":"Mecklenburg-Vorpommern","8":"Niedersachsen","9":"Nordrhein-Westfalen","A":"Rheinland-Pfalz", + "B":"Saarland","C":"Sachsen","D":"Sachsen-Anhalt","E":"Schleswig-Holstein","F":"Thüringen"} + if list(PI)[0] in "D1": + pi_str+="germany?, " + pi_str+=bundeslaender[list(PI)[2]]+", " + pi_str+="NR:"+list(PI)[3] + self.RDS_data[PI]["CC"]=list(PI)[0] + self.RDS_data[PI]["PI-meaning"]=pi_str self.RDS_data[PI]["blockcounts"]={"0A":0,"1A":0,"2A":0,"3A":0,"4A":0,"6A":0,"8A":0,"12A":0,"14A":0} self.RDS_data[PI]["blockcounts"]["any"]=0 self.RDS_data[PI]["AID_list"]={} @@ -1661,10 +1684,21 @@ class rds_parser_table_qt(gr.sync_block):#START def decode_chars(self,charstring): alphabet={ + 0b0010:u" !\#¤%&'()*+,-./", + 0b0011:u"0123456789:;<=>?", + 0b0100:u"@ABCDEFGHIJKLMNO", + 0b0101:u"PQRSTUVWXYZ[\]―_", + 0b0110:u"‖abcdefghijklmno", + 0b0111:u"pqrstuvwxyz{|}¯ ", 0b1000:u"áàéèíìóòúùÑÇŞßiIJ", - 0b1001:u"âäêëîïôöûüñçş??ij", + 0b1001:u"âäêëîïôöûüñçşǧıij", + 0b1010:u"ªα©‰Ǧěňőπ€£$←↑→↓", + 0b1011:u"º¹²³±İńűµ¿÷°¼½¾§", 0b1100:u"ÁÀÉÈÍÌÓÒÚÙŘČŠŽĐĿ", - 0b1101:u"ÂÄÊËÎÏÔÖÛÜřčšžđŀ"} + 0b1101:u"ÂÄÊËÎÏÔÖÛÜřčšžđŀ", + 0b1110:u"ÃÅÆŒŷÝÕØÞŊŔĆŚŹŦð", + 0b1111:u"ãåæœŵýõøþŋŕćśźŧ"}#0xff should not occur (not in standard) + #charlist=list(charstring) return_string="" for i,char in enumerate(charstring): @@ -1677,20 +1711,16 @@ class rds_parser_table_qt(gr.sync_block):#START return_string+=char else: return_string+="{%02X}"%ord(char)#output control code - elif ord(char)<= 0b01111111: - #charlist[i]=char #use ascii - return_string+=char +# elif ord(char)<= 0b01111111: #real encoding slightly different from ascii +# return_string+=char#use ascii else: try: - #charlist[i]=alphabet[alnr][index] return_string+=alphabet[alnr][index] - return_string+=unichr(ord(char))#TODO remove test code and properly decide for UTF8 or EBU charset + #return_string+=unichr(ord(char))#TODO: properly decide for UTF8 or EBU charset except KeyError: - return_string+="?%02X?"%ord(char) + return_string+="?%02X?"%ord(char)#symbol not decoded print("symbol not decoded: "+"?%02X?"%ord(char)+"in string:"+return_string) - #charlist[i]='?'#symbol not decoded #TODO pass - #return "".join(charlist) return return_string def color_text(self, text, start,end,textcolor,segmentcolor): #formatted_text="%s%s%s"% (textcolor,text[:start],segmentcolor,text[start:end],textcolor,text[end:]) diff --git a/swig/crfa_swig.i b/swig/crfa_swig.i index cfc0b0c..606ab65 100644 --- a/swig/crfa_swig.i +++ b/swig/crfa_swig.i @@ -11,6 +11,7 @@ #include "crfa/rds_decoder.h" #include "crfa/diff_add_sync_decim.h" #include "crfa/sync_decim.h" +#include "crfa/rds_decoder_redsea.h" %} %include "crfa/rds_decoder.h" @@ -19,3 +20,5 @@ GR_SWIG_BLOCK_MAGIC2(crfa, rds_decoder); GR_SWIG_BLOCK_MAGIC2(crfa, diff_add_sync_decim); %include "crfa/sync_decim.h" GR_SWIG_BLOCK_MAGIC2(crfa, sync_decim); +%include "crfa/rds_decoder_redsea.h" +GR_SWIG_BLOCK_MAGIC2(crfa, rds_decoder_redsea);