diff --git a/.gitignore b/.gitignore index bee6f383..8300b471 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,4 @@ log_default.conf python/.unittests/ .idea/ examples/top_block.py +python/GUI/user_frontend.py diff --git a/CMakeLists.txt b/CMakeLists.txt index f0266b8e..3e2aba12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,7 +81,7 @@ else() message(STATUS "LIBTOOLAME-DAB found: ${LIBTOOLAME-DAB_SOURCE_DIR}") endif () - +find_package(PyQt4 REQUIRED) ######################################################################## # Find boost ######################################################################## diff --git a/README.md b/README.md index 5706993a..b899cc14 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ Contents 2: Installation -3: Features +3: Usage -4: Usage +4: Features 5: Current Constraints @@ -63,7 +63,6 @@ fulfilled. All my code got merged into the master branch of this repository. This fork will serve as upstream repository for further development of the OFDM receiver (especially with respect to synchronization), and other improvements. - Installation ------------ @@ -106,6 +105,7 @@ Features * Receiving and Transmitting DAB/DAB+ broadcasts with the graphical application "DABstep" * Receiving or Transmitting DAB/DAB+ with prepaired GNU Radio Companion flowgraph in examples/ * Receiving or Transmitting DAB/DAB+ by building your own GNU Radio flowgraph with provided gr-dab blocks +* USRP and RTL-SDR for reception supported Usage ------- @@ -124,16 +124,18 @@ Current Constraints * PAD interpretation and generation not supported so far * only EEP with protection profile set A supported so far, no set B and no UEP + Ideas ---------- * FM simulation, calculating the audio noise out of the SNR and adding it to the audio * parallel FM receiver that fills in the audio in case a superframe is broken +* include reception and transmission of data channels with packed data, e.g. pictures Known Bugs ---------- -* OFDM demodulator gets out of sync sometimes causing burst errors +* Audio underruns disturb played audio signal without having actual errors. Additional buffer through delay block is a temporary fix that only works until reception errors occur. Documentation -------------- diff --git a/apps/DABstep b/apps/DABstep index 35dd3a1c..c7ed0f3e 100755 --- a/apps/DABstep +++ b/apps/DABstep @@ -51,6 +51,7 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): self.need_new_init = True self.file_path = "None" self.src_is_USRP = True + self.src_is_RTL = False self.receiver_running = False self.audio_playing = False self.recording = False @@ -70,6 +71,7 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): self.snr_timer.timeout.connect(self.snr_update) # change of source by radio buttons self.rbtn_USRP.clicked.connect(self.src2USRP) + self.rbtn_RTL.clicked.connect(self.src2RTL) self.rbtn_File.clicked.connect(self.src2File) # set file path self.btn_file_path.clicked.connect(self.set_file_path) @@ -84,6 +86,8 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): # adjust audio sampling rate self.timer_audio_sampling_rate = QTimer() self.timer_audio_sampling_rate.timeout.connect(self.adjust_audio_sampling_rate) + # gain setter + self.gain_spin.valueChanged.connect(self.set_rx_gain) # stop button click stops audio reception self.btn_stop.hide() self.btn_stop.clicked.connect(self.stop_audio) @@ -176,6 +180,8 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): self.t_btn_stop.pressed.connect(self.t_stop_transmitter) # path for File sink path self.t_btn_file_path.pressed.connect(self.t_set_file_path) + # gain setter + self.tx_gain.valueChanged.connect(self.set_tx_gain) # path selection for all 7 (possible) sub channels self.t_btn_path_src1.pressed.connect(self.t_set_subch_path1) self.t_btn_path_src2.pressed.connect(self.t_set_subch_path2) @@ -200,6 +206,7 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): self.t_combo_dabplus7.currentIndexChanged.connect(self.change_audio_bit_rates7) # set volume if volume slider is changed self.t_slider_volume.valueChanged.connect(self.t_set_volume) + self.transmitter_running = False ################################ # general functions @@ -225,6 +232,16 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): self.spinbox_frequency.setEnabled(True) self.label_frequency.setEnabled(True) self.src_is_USRP = True + self.src_is_RTL = False + + def src2RTL(self): + # enable/disable buttons + self.btn_file_path.setEnabled(False) + self.label_path.setEnabled(False) + self.spinbox_frequency.setEnabled(True) + self.label_frequency.setEnabled(True) + self.src_is_RTL = True + self.src_is_USRP = False def src2File(self): # enable/disable buttons @@ -233,6 +250,7 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): self.spinbox_frequency.setEnabled(False) self.label_frequency.setEnabled(False) self.src_is_USRP = False + self.src_is_RTL = False def set_file_path(self): path = QtGui.QFileDialog.getOpenFileName(self, "Pick a file with recorded IQ samples") @@ -247,13 +265,13 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): self.snr_timer.stop() self.firecode_timer.stop() # check if file path is selected in case that file is the selected source - if (not self.src_is_USRP) and (self.file_path == "None"): + if (not self.src_is_USRP) and (not self.src_is_RTL) and (self.file_path == "None"): self.label_path.setStyleSheet('color: red') else: self.label_path.setStyleSheet('color: black') # set up and start flowgraph self.my_receiver = usrp_dab_rx.usrp_dab_rx(self.spin_dab_mode.value(), self.spinbox_frequency.value(), self.bit_rate, self.address, self.size, self.protection, self.audio_bit_rate, self.dabplus, - self.src_is_USRP, self.file_path) + self.src_is_USRP, self.src_is_RTL, self.file_path) self.my_receiver.set_volume(0) self.my_receiver.start() # status bar @@ -275,6 +293,11 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): self.receiver_running = True self.btn_init.setText("stop receiver") else: + # stop receiver was pressed + self.dev_mode_close() + # remove service table + while (self.table_mci.rowCount() > 0): + self.table_mci.removeRow(0) self.my_receiver.stop() self.receiver_running = False self.btn_init.setText("start receiver") @@ -287,6 +310,21 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): self.btn_stop.hide() self.audio_playing = False self.statusBar.showMessage("Receiver stopped.") + self.bar_snr.setValue(0) + # reset variables + self.bit_rate = 8 + self.address = 0 + self.size = 6 + self.protection = 2 + self.audio_bit_rate = 16000 + self.volume = 80 + self.subch = -1 + self.dabplus = True + self.need_new_init = True + self.file_path = "None" + self.receiver_running = False + self.audio_playing = False + self.recording = False def update_service_info(self): # set status bar message @@ -372,24 +410,24 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): self.statusBar.showMessage("Play/Record the selected service component.") def snr_update(self): - print "update snr" # display snr in progress bar if an instance of usrp_dab_rx is existing - if hasattr(self, 'my_receiver'): + if hasattr(self, 'my_receiver') and self.receiver_running: SNR = self.my_receiver.get_snr() - if SNR > 10: + if SNR > 15.0: self.setStyleSheet("""QProgressBar::chunk { background: "green"; }""") - if SNR > 20: - SNR = 20 - elif 5 < SNR <= 10: + elif SNR > 10.0: self.setStyleSheet("""QProgressBar::chunk { background: "yellow"; }""") - else: + elif SNR <= 10.0: self.setStyleSheet("""QProgressBar::chunk { background: "red"; }""") - if SNR < -20 or math.isnan(SNR): - SNR = -20 - self.bar_snr.setValue(SNR) self.lcd_snr.display(SNR) + if SNR > 40: + SNR = 20 + elif SNR < 0: + SNR = 0 + self.bar_snr.setValue(int(SNR)) + else: - self.bar_snr.setValue(-20) + self.bar_snr.setValue(0) self.label_snr.setText("SNR: no reception") self.snr_timer.start(1000) @@ -405,11 +443,12 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): self.snr_timer.stop() self.firecode_timer.stop() self.my_receiver.stop() + self.temp_src = self.my_receiver.src self.my_receiver = usrp_dab_rx.usrp_dab_rx(self.spin_dab_mode.value(), self.spinbox_frequency.value(), self.bit_rate, self.address, self.size, self.protection, self.audio_bit_rate, self.dabplus, - self.src_is_USRP, self.file_path) + self.src_is_USRP, self.src_is_RTL, self.file_path, prev_src=self.temp_src) self.my_receiver.set_volume(float(self.slider_volume.value()) / 100) self.my_receiver.start() self.statusBar.showMessage("Audio playing.") @@ -436,7 +475,6 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): def adjust_audio_sampling_rate(self): self.timer_audio_sampling_rate.stop() new_sampling_rate = self.my_receiver.get_sample_rate() - print "key adjust" if new_sampling_rate != self.audio_bit_rate and new_sampling_rate != -1: self.audio_bit_rate = new_sampling_rate self.statusBar.showMessage("Adjusting audio sampling rate to " + str(new_sampling_rate)) @@ -445,7 +483,7 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): self.spinbox_frequency.value(), self.bit_rate, self.address, self.size, self.protection, self.audio_bit_rate, self.dabplus, - self.src_is_USRP, self.file_path) + self.src_is_USRP, self.src_is_RTL, self.file_path, prev_src=self.temp_src) self.my_receiver.start() elif new_sampling_rate == -1: @@ -704,81 +742,87 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): component["combo_audio_rate"].hide() def t_init_transmitter(self): - self.statusBar.showMessage("initializing transmitter...") - # boolean is set to True if info is missing to init the transmitter - arguments_incomplete = False - # produce array for protection and data_rate and src_paths and stereo flags - num_subch = self.t_spin_num_subch.value() - protection_array = [None] * num_subch - data_rate_n_array = [None] * num_subch - audio_sampling_rate_array = [None] * num_subch - audio_paths = [None] * num_subch - stereo_flags = [None] * num_subch - merged_service_string = "" - dabplus_types = [True] * num_subch - record_states = [False] * num_subch - for i in range(0, num_subch): - # write array with protection modes - protection_array[i] = self.components[i]["protection"].currentIndex() - # write array with data rates - data_rate_n_array[i] = self.components[i]["data_rate"].value()/8 - # write stereo flags - stereo_flags[i] = self.components[i]["combo_stereo"].currentIndex() - # write audio sampling rates in array - if self.components[i]["combo_dabplus"].currentIndex() is 0: - audio_sampling_rate_array[i] = 32000 if (self.components[i]["combo_audio_rate"].currentIndex() is 0) else 48000 - else: - audio_sampling_rate_array[i] = 48000 if (self.components[i]["combo_audio_rate_dab"].currentIndex() is 0) else 24000 - # check audio paths - if self.components[i]["src_path"] is "None": - # highlight the path which is not selected - self.components[i]["src_path_disp"].setStyleSheet('color: red') - arguments_incomplete = True - self.statusBar.showMessage("path " + str(i+1) + " not selected") - # check if length of label is <= 16 chars - elif len(str(self.components[i]["edit_label"].text())) > 16: - self.components[i]["edit_label"].setStyleSheet('color: red') + if self.transmitter_running: + self.transmitter_running = False + self.t_btn_init.setText("start transmitter") + else: + self.transmitter_running = True + self.t_btn_init.setText("stop transmitter") + self.statusBar.showMessage("initializing transmitter...") + # boolean is set to True if info is missing to init the transmitter + arguments_incomplete = False + # produce array for protection and data_rate and src_paths and stereo flags + num_subch = self.t_spin_num_subch.value() + protection_array = [None] * num_subch + data_rate_n_array = [None] * num_subch + audio_sampling_rate_array = [None] * num_subch + audio_paths = [None] * num_subch + stereo_flags = [None] * num_subch + merged_service_string = "" + dabplus_types = [True] * num_subch + record_states = [False] * num_subch + for i in range(0, num_subch): + # write array with protection modes + protection_array[i] = self.components[i]["protection"].currentIndex() + # write array with data rates + data_rate_n_array[i] = self.components[i]["data_rate"].value()/8 + # write stereo flags + stereo_flags[i] = self.components[i]["combo_stereo"].currentIndex() + # write audio sampling rates in array + if self.components[i]["combo_dabplus"].currentIndex() is 0: + audio_sampling_rate_array[i] = 32000 if (self.components[i]["combo_audio_rate"].currentIndex() is 0) else 48000 + else: + audio_sampling_rate_array[i] = 48000 if (self.components[i]["combo_audio_rate_dab"].currentIndex() is 0) else 24000 + # check audio paths + if self.components[i]["src_path"] is "None": + # highlight the path which is not selected + self.components[i]["src_path_disp"].setStyleSheet('color: red') + arguments_incomplete = True + self.statusBar.showMessage("path " + str(i+1) + " not selected") + # check if length of label is <= 16 chars + elif len(str(self.components[i]["edit_label"].text())) > 16: + self.components[i]["edit_label"].setStyleSheet('color: red') + arguments_incomplete = True + self.statusBar.showMessage("Warning: Label is longer than 16 characters!") + else: + audio_paths[i] = self.components[i]["src_path"] + # write service labels appended in one string + merged_service_string = merged_service_string + str(self.components[i]["edit_label"].text()).ljust(16) + self.components[i]["edit_label"].setStyleSheet('color: black') + # write dabplus types + dabplus_types[i] = (1 if self.components[i]["combo_dabplus"].currentIndex() is 0 else 0) + + # check if length of ensemble label is <= 16 chars + if len(str(self.t_edit_ensemble_label.text())) > 16: + self.t_edit_ensemble_label.setStyleSheet('color: red') arguments_incomplete = True - self.statusBar.showMessage("Warning: Label is longer than 16 characters!") else: - audio_paths[i] = self.components[i]["src_path"] - # write service labels appended in one string - merged_service_string = merged_service_string + str(self.components[i]["edit_label"].text()).ljust(16) - self.components[i]["edit_label"].setStyleSheet('color: black') - # write dabplus types - dabplus_types[i] = (1 if self.components[i]["combo_dabplus"].currentIndex() is 0 else 0) - - # check if length of ensemble label is <= 16 chars - if len(str(self.t_edit_ensemble_label.text())) > 16: - self.t_edit_ensemble_label.setStyleSheet('color: red') - arguments_incomplete = True - else: - self.t_edit_ensemble_label.setStyleSheet('color: black') - # check if File path for sink is chosen if option enabled - if self.t_rbtn_File.isChecked() and (str(self.t_label_sink.text()) == "select path"): - self.t_label_sink.setStyleSheet('color: red') - arguments_incomplete = True - - if arguments_incomplete is False: - # init transmitter - self.my_transmitter = usrp_dab_tx.usrp_dab_tx(self.t_spin_dab_mode.value(), - self.t_spinbox_frequency.value(), - self.t_spin_num_subch.value(), - str(self.t_edit_ensemble_label.text()), - merged_service_string, - self.t_combo_language.currentIndex(), self.t_combo_country.currentIndex(), - protection_array, data_rate_n_array, stereo_flags, audio_sampling_rate_array, - audio_paths, - self.t_spin_listen_to_component.value(), - self.t_rbtn_USRP.isChecked(), - dabplus_types, - str(self.t_label_sink.text()) + "/" + str( - self.t_edit_file_name.text())) - - # enable play button - self.t_btn_play.setEnabled(True) - self.t_label_status.setText("ready to transmit") - self.statusBar.showMessage("ready to transmit") + self.t_edit_ensemble_label.setStyleSheet('color: black') + # check if File path for sink is chosen if option enabled + if self.t_rbtn_File.isChecked() and (str(self.t_label_sink.text()) == "select path"): + self.t_label_sink.setStyleSheet('color: red') + arguments_incomplete = True + + if arguments_incomplete is False: + # init transmitter + self.my_transmitter = usrp_dab_tx.usrp_dab_tx(self.t_spin_dab_mode.value(), + self.t_spinbox_frequency.value(), + self.t_spin_num_subch.value(), + str(self.t_edit_ensemble_label.text()), + merged_service_string, + self.t_combo_language.currentIndex(), self.t_combo_country.currentIndex(), + protection_array, data_rate_n_array, stereo_flags, audio_sampling_rate_array, + audio_paths, + self.t_spin_listen_to_component.value(), + self.t_rbtn_USRP.isChecked(), + dabplus_types, + str(self.t_label_sink.text()) + "/" + str( + self.t_edit_file_name.text())) + + # enable play button + self.t_btn_play.setEnabled(True) + self.t_label_status.setText("ready to transmit") + self.statusBar.showMessage("ready to transmit") def t_run_transmitter(self): self.t_btn_stop.setEnabled(True) @@ -953,6 +997,14 @@ class DABstep(QtGui.QMainWindow, user_frontend.Ui_MainWindow): self.t_combo_audio_rate_dab7.show() self.t_combo_audio_rate7.hide() + def set_rx_gain(self): + if hasattr(self, 'my_receiver'): + self.my_receiver.set_gain(self.gain_spin.value()) + + def set_tx_gain(self): + if hasattr(self, 'my_transmitter'): + self.my_transmitter.set_gain(self.tx_gain.value()) + class lookup_tables: languages = [ @@ -1074,3 +1126,4 @@ def main(): if __name__ == '__main__': main() + diff --git a/cmake/Modules/FindPyQt4.cmake b/cmake/Modules/FindPyQt4.cmake new file mode 100644 index 00000000..c1f3f288 --- /dev/null +++ b/cmake/Modules/FindPyQt4.cmake @@ -0,0 +1,61 @@ +# Find PyQt4 +# ~~~~~~~~~~ +# Copyright (c) 2007-2008, Simon Edwards +# Copyright (c) 2012, Nicholas Corgan +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# +# PyQt4 website: http://www.riverbankcomputing.co.uk/pyqt/index.php +# +# Find the installed version of PyQt4. FindPyQt4 should only be called after +# Python has been found. +# +# This file defines the following variables: +# +# PYQT4_VERSION - The version of PyQt4 found expressed as a 6 digit hex number +# suitable for comparision as a string +# +# PYQT4_VERSION_STR - The version of PyQt4 as a human readable string. +# +# PYQT4_VERSION_TAG - The PyQt version tag using by PyQt's sip files. +# +# PYQT4_SIP_DIR - The directory holding the PyQt4 .sip files. +# +# PYQT4_SIP_FLAGS - The SIP flags used to build PyQt. + +IF(EXISTS PYQT4_VERSION AND EXISTS PYUIC4_EXECUTABLE) + # Already in cache, be silent + SET(PYQT4_FOUND TRUE) + SET(PYUIC4_FOUND TRUE) +ELSE(EXISTS PYQT4_VERSION AND EXISTS PYUIC4_EXECUTABLE) + + FIND_FILE(_find_pyqt_py FindPyQt.py PATHS ${CMAKE_MODULE_PATH}) + + EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_pyqt_py} OUTPUT_VARIABLE pyqt_config) + IF(pyqt_config) + STRING(REGEX REPLACE "^pyqt_version:([^\n]+).*$" "\\1" PYQT4_VERSION ${pyqt_config}) + STRING(REGEX REPLACE ".*\npyqt_version_str:([^\n]+).*$" "\\1" PYQT4_VERSION_STR ${pyqt_config}) + STRING(REGEX REPLACE ".*\npyqt_version_tag:([^\n]+).*$" "\\1" PYQT4_VERSION_TAG ${pyqt_config}) + STRING(REGEX REPLACE ".*\npyqt_sip_dir:([^\n]+).*$" "\\1" PYQT4_SIP_DIR ${pyqt_config}) + STRING(REGEX REPLACE ".*\npyqt_sip_flags:([^\n]+).*$" "\\1" PYQT4_SIP_FLAGS ${pyqt_config}) + + SET(PYQT4_FOUND TRUE) + ENDIF(pyqt_config) + + FIND_PROGRAM(PYUIC4_EXECUTABLE NAMES pyuic4) + IF(PYUIC4_EXECUTABLE) + SET(PYUIC4_FOUND TRUE) + ENDIF(PYUIC4_EXECUTABLE) + + IF(PYQT4_FOUND AND PYUIC4_FOUND) + IF(NOT PYQT4_FIND_QUIETLY) + MESSAGE(STATUS "Found PyQt4 version: ${PYQT4_VERSION_STR}") + MESSAGE(STATUS "Found pyuic4: ${PYUIC4_EXECUTABLE}") + ENDIF(NOT PYQT4_FIND_QUIETLY) + ELSE(PYQT4_FOUND AND PYUIC4_FOUND) + IF(PYQT4_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find Python") + ENDIF(PYQT4_FIND_REQUIRED) + ENDIF(PYQT4_FOUND AND PYUIC4_FOUND) + +ENDIF(EXISTS PYQT4_VERSION AND EXISTS PYUIC4_EXECUTABLE) diff --git a/examples/dab_receiver.grc b/examples/dab_receiver.grc index d84a587a..93cb2187 100644 --- a/examples/dab_receiver.grc +++ b/examples/dab_receiver.grc @@ -81,6 +81,45 @@ + + variable_qtgui_entry + + comment + + + + value + 201072000 + + + _enabled + True + + + _coordinate + (855, 12) + + + gui_hint + + + + _rotation + 0 + + + id + freq + + + label + Frequency + + + type + int + + variable_qtgui_range @@ -168,7 +207,7 @@ value - 2000000 + 2048000 @@ -191,11 +230,11 @@ _enabled - True + 1 _coordinate - (928, 401) + (905, 417) _rotation @@ -219,11 +258,7 @@ - blocks_file_sink - - append - False - + blocks_file_source alias @@ -238,15 +273,15 @@ _enabled - True + 0 file - /home/luca/Desktop/iq_dab_neu.dat + _coordinate - (616, 542) + (133, 433) _rotation @@ -254,62 +289,23 @@ id - blocks_file_sink_0 - - - type - complex - - - unbuffered - False - - - vlen - 1 - - - - blocks_null_sink - - alias - - - - bus_conns - [[0,],] - - - comment - + blocks_file_source_0 - affinity - - - - _enabled - 1 - - - _coordinate - (1016, 297) - - - _rotation + maxoutbuf 0 - id - blocks_null_sink_0_1 + minoutbuf + 0 type - byte + complex - num_inputs - 1 + repeat + True vlen @@ -336,7 +332,7 @@ _coordinate - (672, 188) + (675, 189) _rotation @@ -367,62 +363,11 @@ 1 - - blocks_vector_to_stream - - alias - - - - comment - - - - affinity - - - - _enabled - 1 - - - _coordinate - (832, 292) - - - _rotation - 0 - - - id - blocks_vector_to_stream_0_1 - - - type - byte - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - num_items - 32 - - - vlen - 1 - - dab_dabplus_audio_decoder_ff address - 234 + 54 bit_rate @@ -446,11 +391,11 @@ _enabled - True + 1 _coordinate - (672, 370) + (687, 386) _rotation @@ -486,7 +431,7 @@ - dab_fic_decode + dab_fic_decode_vc alias @@ -509,7 +454,7 @@ _coordinate - (640, 281) + (674, 274) _rotation @@ -517,15 +462,7 @@ id - dab_fic_decode_0 - - - maxoutbuf - 0 - - - minoutbuf - 0 + dab_fic_decode_vc_0 samp_rate @@ -533,11 +470,7 @@ - dab_ofdm_demod - - autocorr_sr - True - + dab_ofdm_demod_cc alias @@ -556,19 +489,11 @@ _enabled - 1 - - - eq_mag - True - - - correct_ffe True _coordinate - (352, 264) + (415, 286) _rotation @@ -576,11 +501,7 @@ id - dab_ofdm_demod_0 - - - input_fft - True + dab_ofdm_demod_cc_0 maxoutbuf @@ -594,36 +515,29 @@ samp_rate samp_rate - - soft_bits - soft - - digital_mpsk_snr_est_cc + note alias comment - - - - affinity - + 1. Enable the data source of your choice and set the center frequency for hardware devices +2. Run flowgraph and adjust gain +3. Read fib_sink info in the console to get the DAB Decoder info +4. Set the DAB+ Decoder info and restart flowgraph + +Execute "DABstep" out of your terminal for a more user-friendly graphical application _enabled True - - alpha - 0.001 - _coordinate - (840, 174) + (301, 8) _rotation @@ -631,400 +545,2407 @@ id - digital_mpsk_snr_est_cc_0 - - - maxoutbuf - 0 - - - minoutbuf - 0 - - - tag_nsamples - 10000 + note_0 - type - 0 + note + Instructions: - note + qtgui_const_sink_x + + autoscale + False + alias comment - 1. Set frequency in USRP -2. Run flowgraph and read fib_sink info in the console to get the DAB+ Decoder info -3. Set the DAB+ Decoder info and restart flowgraph -4. Adjust sampling rate + + + + affinity + _enabled - True + 1 _coordinate - (304, 12) + (869, 182) + + + gui_hint + _rotation 0 + + grid + False + id - note_0 + qtgui_const_sink_x_1 - note - Instructions: + legend + True - - - qtgui_const_sink_x - autoscale - False + alpha1 + 1.0 - alias - + color1 + "blue" - comment + label1 - affinity + marker1 + 0 + + + style1 + 0 + + + width1 + 1 + + + alpha10 + 1.0 + + + color10 + "red" + + + label10 - _enabled - True + marker10 + 0 - _coordinate - (1056, 181) + style10 + 0 + + + width10 + 1 + + + alpha2 + 1.0 + + + color2 + "red" + + + label2 + + + + marker2 + 0 + + + style2 + 0 + + + width2 + 1 + + + alpha3 + 1.0 + + + color3 + "red" + + + label3 + + + + marker3 + 0 + + + style3 + 0 + + + width3 + 1 + + + alpha4 + 1.0 + + + color4 + "red" + + + label4 + + + + marker4 + 0 + + + style4 + 0 + + + width4 + 1 + + + alpha5 + 1.0 + + + color5 + "red" + + + label5 + + + + marker5 + 0 + + + style5 + 0 + + + width5 + 1 + + + alpha6 + 1.0 + + + color6 + "red" + + + label6 + + + + marker6 + 0 + + + style6 + 0 + + + width6 + 1 + + + alpha7 + 1.0 + + + color7 + "red" + + + label7 + + + + marker7 + 0 + + + style7 + 0 + + + width7 + 1 + + + alpha8 + 1.0 + + + color8 + "red" + + + label8 + + + + marker8 + 0 + + + style8 + 0 + + + width8 + 1 + + + alpha9 + 1.0 + + + color9 + "red" + + + label9 + + + + marker9 + 0 + + + style9 + 0 + + + width9 + 1 + + + name + "" + + + nconnections + 1 + + + size + 1024 + + + tr_chan + 0 + + + tr_level + 0.0 + + + tr_mode + qtgui.TRIG_MODE_FREE + + + tr_slope + qtgui.TRIG_SLOPE_POS + + + tr_tag + "" + + + type + complex + + + update_time + 0.10 + + + xmax + 2 + + + xmin + -2 + + + ymax + 2 + + + ymin + -2 + + + + qtgui_freq_sink_x + + autoscale + False + + + average + 1.0 + + + bw + samp_rate + + + alias + + + + fc + 0 + + + comment + + + + ctrlpanel + False + + + affinity + + + + _enabled + True + + + fftsize + 1024 + + + _coordinate + (416, 191) + + + gui_hint + + + + _rotation + 0 + + + grid + False + + + id + qtgui_freq_sink_x_0 + + + legend + True + + + alpha1 + 1.0 + + + color1 + "blue" + + + label1 + + + + width1 + 1 + + + alpha10 + 1.0 + + + color10 + "dark blue" + + + label10 + + + + width10 + 1 + + + alpha2 + 1.0 + + + color2 + "red" + + + label2 + + + + width2 + 1 + + + alpha3 + 1.0 + + + color3 + "green" + + + label3 + + + + width3 + 1 + + + alpha4 + 1.0 + + + color4 + "black" + + + label4 + + + + width4 + 1 + + + alpha5 + 1.0 + + + color5 + "cyan" + + + label5 + + + + width5 + 1 + + + alpha6 + 1.0 + + + color6 + "magenta" + + + label6 + + + + width6 + 1 + + + alpha7 + 1.0 + + + color7 + "yellow" + + + label7 + + + + width7 + 1 + + + alpha8 + 1.0 + + + color8 + "dark red" + + + label8 + + + + width8 + 1 + + + alpha9 + 1.0 + + + color9 + "dark green" + + + label9 + + + + width9 + 1 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + name + "" + + + nconnections + 1 + + + showports + True + + + freqhalf + True + + + tr_chan + 0 + + + tr_level + 0.0 + + + tr_mode + qtgui.TRIG_MODE_FREE + + + tr_tag + "" + + + type + complex + + + update_time + 0.10 + + + wintype + firdes.WIN_BLACKMAN_hARRIS + + + ymax + 10 + + + ymin + -140 + + + + qtgui_time_sink_x + + autoscale + False + + + alias + + + + comment + + + + ctrlpanel + False + + + affinity + + + + entags + True + + + _enabled + 1 + + + _coordinate + (418, 381) + + + gui_hint + + + + _rotation + 0 + + + grid + False + + + id + qtgui_time_sink_x_0 + + + legend + True + + + alpha1 + 1.0 + + + color1 + "blue" + + + label1 + + + + marker1 + -1 + + + style1 + 1 + + + width1 + 1 + + + alpha10 + 1.0 + + + color10 + "blue" + + + label10 + + + + marker10 + -1 + + + style10 + 1 + + + width10 + 1 + + + alpha2 + 1.0 + + + color2 + "red" + + + label2 + + + + marker2 + -1 + + + style2 + 1 + + + width2 + 1 + + + alpha3 + 1.0 + + + color3 + "green" + + + label3 + + + + marker3 + -1 + + + style3 + 1 + + + width3 + 1 + + + alpha4 + 1.0 + + + color4 + "black" + + + label4 + + + + marker4 + -1 + + + style4 + 1 + + + width4 + 1 + + + alpha5 + 1.0 + + + color5 + "cyan" + + + label5 + + + + marker5 + -1 + + + style5 + 1 + + + width5 + 1 + + + alpha6 + 1.0 + + + color6 + "magenta" + + + label6 + + + + marker6 + -1 + + + style6 + 1 + + + width6 + 1 + + + alpha7 + 1.0 + + + color7 + "yellow" + + + label7 + + + + marker7 + -1 + + + style7 + 1 + + + width7 + 1 + + + alpha8 + 1.0 + + + color8 + "dark red" + + + label8 + + + + marker8 + -1 + + + style8 + 1 + + + width8 + 1 + + + alpha9 + 1.0 + + + color9 + "dark green" + + + label9 + + + + marker9 + -1 + + + style9 + 1 + + + width9 + 1 + + + name + "" + + + nconnections + 1 + + + size + 1024 + + + srate + samp_rate + + + tr_chan + 0 + + + tr_delay + 0 + + + tr_level + 0.0 + + + tr_mode + qtgui.TRIG_MODE_FREE + + + tr_slope + qtgui.TRIG_SLOPE_POS + + + tr_tag + "" + + + type + complex + + + update_time + 0.10 + + + ylabel + Amplitude + + + yunit + "" + + + ymax + 1 + + + ymin + -1 + + + + rtlsdr_source + + alias + + + + ant0 + + + + bb_gain0 + 20 + + + bw0 + 0 + + + dc_offset_mode0 + 2 + + + corr0 + 0 + + + freq0 + freq + + + gain_mode0 + False + + + if_gain0 + 20 + + + iq_balance_mode0 + 0 + + + gain0 + gain_slider + + + ant10 + + + + bb_gain10 + 20 + + + bw10 + 0 + + + dc_offset_mode10 + 0 + + + corr10 + 0 + + + freq10 + 100e6 + + + gain_mode10 + False + + + if_gain10 + 20 + + + iq_balance_mode10 + 0 + + + gain10 + 10 + + + ant11 + + + + bb_gain11 + 20 + + + bw11 + 0 + + + dc_offset_mode11 + 0 + + + corr11 + 0 + + + freq11 + 100e6 + + + gain_mode11 + False + + + if_gain11 + 20 + + + iq_balance_mode11 + 0 + + + gain11 + 10 + + + ant12 + + + + bb_gain12 + 20 + + + bw12 + 0 + + + dc_offset_mode12 + 0 + + + corr12 + 0 + + + freq12 + 100e6 + + + gain_mode12 + False + + + if_gain12 + 20 + + + iq_balance_mode12 + 0 + + + gain12 + 10 + + + ant13 + + + + bb_gain13 + 20 + + + bw13 + 0 + + + dc_offset_mode13 + 0 + + + corr13 + 0 + + + freq13 + 100e6 + + + gain_mode13 + False + + + if_gain13 + 20 + + + iq_balance_mode13 + 0 + + + gain13 + 10 + + + ant14 + + + + bb_gain14 + 20 + + + bw14 + 0 + + + dc_offset_mode14 + 0 + + + corr14 + 0 + + + freq14 + 100e6 + + + gain_mode14 + False + + + if_gain14 + 20 + + + iq_balance_mode14 + 0 + + + gain14 + 10 + + + ant15 + + + + bb_gain15 + 20 + + + bw15 + 0 + + + dc_offset_mode15 + 0 + + + corr15 + 0 + + + freq15 + 100e6 + + + gain_mode15 + False + + + if_gain15 + 20 + + + iq_balance_mode15 + 0 + + + gain15 + 10 + + + ant16 + + + + bb_gain16 + 20 + + + bw16 + 0 + + + dc_offset_mode16 + 0 + + + corr16 + 0 + + + freq16 + 100e6 + + + gain_mode16 + False + + + if_gain16 + 20 + + + iq_balance_mode16 + 0 + + + gain16 + 10 + + + ant17 + + + + bb_gain17 + 20 + + + bw17 + 0 + + + dc_offset_mode17 + 0 + + + corr17 + 0 + + + freq17 + 100e6 + + + gain_mode17 + False + + + if_gain17 + 20 + + + iq_balance_mode17 + 0 + + + gain17 + 10 + + + ant18 + + + + bb_gain18 + 20 + + + bw18 + 0 + + + dc_offset_mode18 + 0 + + + corr18 + 0 + + + freq18 + 100e6 + + + gain_mode18 + False + + + if_gain18 + 20 + + + iq_balance_mode18 + 0 + + + gain18 + 10 + + + ant19 + + + + bb_gain19 + 20 + + + bw19 + 0 + + + dc_offset_mode19 + 0 + + + corr19 + 0 + + + freq19 + 100e6 + + + gain_mode19 + False + + + if_gain19 + 20 + + + iq_balance_mode19 + 0 + + + gain19 + 10 + + + ant1 + + + + bb_gain1 + 20 + + + bw1 + 0 + + + dc_offset_mode1 + 0 + + + corr1 + 0 + + + freq1 + 100e6 + + + gain_mode1 + False + + + if_gain1 + 20 + + + iq_balance_mode1 + 0 + + + gain1 + 10 + + + ant20 + + + + bb_gain20 + 20 + + + bw20 + 0 + + + dc_offset_mode20 + 0 + + + corr20 + 0 + + + freq20 + 100e6 + + + gain_mode20 + False + + + if_gain20 + 20 + + + iq_balance_mode20 + 0 + + + gain20 + 10 + + + ant21 + + + + bb_gain21 + 20 + + + bw21 + 0 + + + dc_offset_mode21 + 0 + + + corr21 + 0 + + + freq21 + 100e6 + + + gain_mode21 + False + + + if_gain21 + 20 + + + iq_balance_mode21 + 0 + + + gain21 + 10 + + + ant22 + + + + bb_gain22 + 20 + + + bw22 + 0 + + + dc_offset_mode22 + 0 + + + corr22 + 0 + + + freq22 + 100e6 + + + gain_mode22 + False + + + if_gain22 + 20 + + + iq_balance_mode22 + 0 + + + gain22 + 10 + + + ant23 + + + + bb_gain23 + 20 + + + bw23 + 0 + + + dc_offset_mode23 + 0 + + + corr23 + 0 + + + freq23 + 100e6 + + + gain_mode23 + False + + + if_gain23 + 20 + + + iq_balance_mode23 + 0 + + + gain23 + 10 + + + ant24 + + + + bb_gain24 + 20 + + + bw24 + 0 + + + dc_offset_mode24 + 0 + + + corr24 + 0 + + + freq24 + 100e6 + + + gain_mode24 + False + + + if_gain24 + 20 + + + iq_balance_mode24 + 0 + + + gain24 + 10 + + + ant25 + + + + bb_gain25 + 20 + + + bw25 + 0 + + + dc_offset_mode25 + 0 + + + corr25 + 0 + + + freq25 + 100e6 + + + gain_mode25 + False + + + if_gain25 + 20 + + + iq_balance_mode25 + 0 + + + gain25 + 10 + + + ant26 + + + + bb_gain26 + 20 + + + bw26 + 0 + + + dc_offset_mode26 + 0 + + + corr26 + 0 + + + freq26 + 100e6 + + + gain_mode26 + False + + + if_gain26 + 20 + + + iq_balance_mode26 + 0 + + + gain26 + 10 + + + ant27 + + + + bb_gain27 + 20 + + + bw27 + 0 + + + dc_offset_mode27 + 0 + + + corr27 + 0 + + + freq27 + 100e6 + + + gain_mode27 + False + + + if_gain27 + 20 + + + iq_balance_mode27 + 0 + + + gain27 + 10 + + + ant28 + + + + bb_gain28 + 20 + + + bw28 + 0 + + + dc_offset_mode28 + 0 + + + corr28 + 0 + + + freq28 + 100e6 + + + gain_mode28 + False + + + if_gain28 + 20 + + + iq_balance_mode28 + 0 + + + gain28 + 10 + + + ant29 + + + + bb_gain29 + 20 + + + bw29 + 0 + + + dc_offset_mode29 + 0 + + + corr29 + 0 + + + freq29 + 100e6 + + + gain_mode29 + False + + + if_gain29 + 20 + + + iq_balance_mode29 + 0 + + + gain29 + 10 + + + ant2 + + + + bb_gain2 + 20 + + + bw2 + 0 + + + dc_offset_mode2 + 0 + + + corr2 + 0 + + + freq2 + 100e6 + + + gain_mode2 + False + + + if_gain2 + 20 + + + iq_balance_mode2 + 0 + + + gain2 + 10 + + + ant30 + + + + bb_gain30 + 20 + + + bw30 + 0 + + + dc_offset_mode30 + 0 + + + corr30 + 0 + + + freq30 + 100e6 + + + gain_mode30 + False + + + if_gain30 + 20 + + + iq_balance_mode30 + 0 + + + gain30 + 10 + + + ant31 + + + + bb_gain31 + 20 + + + bw31 + 0 + + + dc_offset_mode31 + 0 + + + corr31 + 0 + + + freq31 + 100e6 + + + gain_mode31 + False + + + if_gain31 + 20 + + + iq_balance_mode31 + 0 + + + gain31 + 10 + + + ant3 + + + + bb_gain3 + 20 + + + bw3 + 0 + + + dc_offset_mode3 + 0 + + + corr3 + 0 + + + freq3 + 100e6 + + + gain_mode3 + False + + + if_gain3 + 20 + + + iq_balance_mode3 + 0 + + + gain3 + 10 + + + ant4 + + + + bb_gain4 + 20 + + + bw4 + 0 + + + dc_offset_mode4 + 0 + + + corr4 + 0 + + + freq4 + 100e6 + + + gain_mode4 + False + + + if_gain4 + 20 + + + iq_balance_mode4 + 0 + + + gain4 + 10 + + + ant5 + + + + bb_gain5 + 20 + + + bw5 + 0 - gui_hint - + dc_offset_mode5 + 0 - _rotation + corr5 0 - grid - False + freq5 + 100e6 - id - qtgui_const_sink_x_1 + gain_mode5 + False - legend - True + if_gain5 + 20 - alpha1 - 1.0 + iq_balance_mode5 + 0 - color1 - "blue" + gain5 + 10 - label1 + ant6 - marker1 - 0 + bb_gain6 + 20 - style1 + bw6 0 - width1 - 1 + dc_offset_mode6 + 0 - alpha10 - 1.0 + corr6 + 0 - color10 - "red" + freq6 + 100e6 - label10 - + gain_mode6 + False - marker10 - 0 + if_gain6 + 20 - style10 + iq_balance_mode6 0 - width10 - 1 - - - alpha2 - 1.0 + gain6 + 10 - color2 - "red" + ant7 + - label2 - + bb_gain7 + 20 - marker2 + bw7 0 - style2 + dc_offset_mode7 0 - width2 - 1 + corr7 + 0 - alpha3 - 1.0 + freq7 + 100e6 - color3 - "red" + gain_mode7 + False - label3 - + if_gain7 + 20 - marker3 + iq_balance_mode7 0 - style3 - 0 + gain7 + 10 - width3 - 1 + ant8 + - alpha4 - 1.0 + bb_gain8 + 20 - color4 - "red" + bw8 + 0 - label4 - + dc_offset_mode8 + 0 - marker4 + corr8 0 - style4 - 0 + freq8 + 100e6 - width4 - 1 + gain_mode8 + False - alpha5 - 1.0 + if_gain8 + 20 - color5 - "red" + iq_balance_mode8 + 0 - label5 + gain8 + 10 + + + ant9 - marker5 - 0 + bb_gain9 + 20 - style5 + bw9 0 - width5 - 1 + dc_offset_mode9 + 0 - alpha6 - 1.0 + corr9 + 0 - color6 - "red" + freq9 + 100e6 - label6 - + gain_mode9 + False - marker6 - 0 + if_gain9 + 20 - style6 + iq_balance_mode9 0 - width6 - 1 - - - alpha7 - 1.0 + gain9 + 10 - color7 - "red" + comment + - label7 + affinity - marker7 - 0 + args + - style7 + _enabled 0 - width7 - 1 - - - alpha8 - 1.0 + _coordinate + (101, 150) - color8 - "red" + _rotation + 0 - label8 - + id + rtlsdr_source_0 - marker8 + maxoutbuf 0 - style8 - 0 + clock_source0 + - width8 - 1 + time_source0 + - alpha9 - 1.0 + clock_source1 + - color9 - "red" + time_source1 + - label9 + clock_source2 - marker9 - 0 + time_source2 + - style9 - 0 + clock_source3 + - width9 - 1 + time_source3 + - name - "" + clock_source4 + - nconnections - 1 + time_source4 + - size - 1024 + clock_source5 + - tr_chan - 0 + time_source5 + - tr_level - 0.0 + clock_source6 + - tr_mode - qtgui.TRIG_MODE_FREE + time_source6 + - tr_slope - qtgui.TRIG_SLOPE_POS + clock_source7 + - tr_tag - "" + time_source7 + - type - complex + minoutbuf + 0 - update_time - 0.10 + nchan + 1 - xmax - 2 + num_mboards + 1 - xmin - -2 + type + fc32 - ymax - 2 + sample_rate + samp_rate - ymin - -2 + sync + @@ -1043,7 +2964,7 @@ center_freq0 - 208064000 + freq dc_offs_enb0 @@ -1931,7 +3852,7 @@ clock_rate - 0.0 + 8*samp_rate comment @@ -1955,7 +3876,7 @@ _coordinate - (104, 271) + (121, 315) _rotation @@ -2107,14 +4028,20 @@ - blocks_vector_to_stream_0 - digital_mpsk_snr_est_cc_0 + blocks_file_source_0 + qtgui_freq_sink_x_0 + 0 + 0 + + + blocks_file_source_0 + qtgui_time_sink_x_0 0 0 - blocks_vector_to_stream_0_1 - blocks_null_sink_0_1 + blocks_vector_to_stream_0 + qtgui_const_sink_x_1 0 0 @@ -2131,56 +4058,56 @@ 1 - dab_fic_decode_0 - blocks_vector_to_stream_0_1 + dab_ofdm_demod_cc_0 + blocks_vector_to_stream_0 0 0 - dab_ofdm_demod_0 - blocks_vector_to_stream_0 + dab_ofdm_demod_cc_0 + dab_fic_decode_vc_0 0 0 - dab_ofdm_demod_0 + dab_ofdm_demod_cc_0 dab_dabplus_audio_decoder_ff_0 - 0 + 1 0 - dab_ofdm_demod_0 - dab_fic_decode_0 + rtlsdr_source_0 + dab_ofdm_demod_cc_0 0 0 - dab_ofdm_demod_0 - dab_dabplus_audio_decoder_ff_0 - 1 - 1 + rtlsdr_source_0 + qtgui_freq_sink_x_0 + 0 + 0 - dab_ofdm_demod_0 - dab_fic_decode_0 - 1 - 1 + rtlsdr_source_0 + qtgui_time_sink_x_0 + 0 + 0 - digital_mpsk_snr_est_cc_0 - qtgui_const_sink_x_1 + uhd_usrp_source_0 + dab_ofdm_demod_cc_0 0 0 uhd_usrp_source_0 - blocks_file_sink_0 + qtgui_freq_sink_x_0 0 0 uhd_usrp_source_0 - dab_ofdm_demod_0 + qtgui_time_sink_x_0 0 0 diff --git a/examples/dab_transmitter.grc b/examples/dab_transmitter.grc index 07a7fad1..192720a6 100644 --- a/examples/dab_transmitter.grc +++ b/examples/dab_transmitter.grc @@ -10,7 +10,7 @@ window_size - + 4096,2048 category @@ -81,6 +81,171 @@ + + variable_qtgui_range + + comment + + + + value + 0.3 + + + _enabled + True + + + _coordinate + (928, 17) + + + gui_hint + + + + _rotation + 0 + + + id + ampl + + + label + Amplitude + + + min_len + 200 + + + orient + Qt.Horizontal + + + start + 0 + + + step + 0.01 + + + stop + 1 + + + rangeType + float + + + widget + counter_slider + + + + variable_qtgui_entry + + comment + + + + value + 201072000 + + + _enabled + True + + + _coordinate + (1184, 30) + + + gui_hint + + + + _rotation + 0 + + + id + freq + + + label + Frequency + + + type + int + + + + variable_qtgui_range + + comment + + + + value + 50 + + + _enabled + True + + + _coordinate + (1064, 17) + + + gui_hint + + + + _rotation + 0 + + + id + gain_range + + + label + Gain + + + min_len + 200 + + + orient + Qt.Horizontal + + + start + 0 + + + step + 1 + + + stop + 100 + + + rangeType + float + + + widget + counter_slider + + variable @@ -105,7 +270,7 @@ value - 2000000 + 2048000 @@ -202,6 +367,57 @@ 1 + + blocks_multiply_const_vxx + + alias + + + + comment + + + + const + ampl + + + affinity + + + + _enabled + True + + + _coordinate + (1127, 252) + + + _rotation + 0 + + + id + blocks_multiply_const_vxx_0 + + + type + complex + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + vlen + 1 + + blocks_stream_to_vector @@ -222,7 +438,7 @@ _coordinate - (704, 228) + (752, 236) _rotation @@ -273,7 +489,7 @@ _coordinate - (672, 294) + (716, 288) _rotation @@ -332,7 +548,7 @@ file - /home/luca/Desktop/SWR3.wav + /home/luca/Desktop/music.wav _coordinate @@ -387,7 +603,7 @@ _coordinate - (448, 217) + (496, 225) _rotation @@ -429,9 +645,13 @@ - dab_mode + coutry_ID 1 + + dabplus + [1] + data_rate_n [14] @@ -442,11 +662,11 @@ ensemble_label - "jfkldsa" + "GNU Radio Tune" _coordinate - (24, 163) + (16, 164) _rotation @@ -464,26 +684,26 @@ minoutbuf 0 + + transmission_mode + 1 + num_subch 1 - protection_mode - [2] + programme_service_labels + "DABstep " - service_comp_label - "fdsas" + protection_mode + [2] service_comp_lang 1 - - programme_service_label - "jkdlsa" - dab_fic_encode @@ -509,7 +729,7 @@ _coordinate - (224, 205) + (304, 213) _rotation @@ -579,172 +799,449 @@ dab_mp4_encode_sb_0 - maxoutbuf - 0 + maxoutbuf + 0 + + + minoutbuf + 0 + + + + dab_msc_encode + + alias + + + + comment + + + + affinity + + + + dab_mode + 1 + + + data_rate_n + 14 + + + _enabled + True + + + _coordinate + (824, 471) + + + _rotation + 0 + + + id + dab_msc_encode_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + protection + 2 + + + samp_rate + samp_rate + + + + dab_ofdm_mod + + alias + + + + comment + + + + affinity + + + + dab_mode + 1 + + + _enabled + True + + + _coordinate + (921, 241) + + + _rotation + 0 + + + id + dab_ofdm_mod_0 + + + maxoutbuf + 0 + + + minoutbuf + 0 + + + samp_rate + samp_rate + + + + note + + alias + + + + comment + 1. Set frequency and clock source (default is external clock for better performance of the transmitter) in USRP +2. Choose audio source (.wav file or audio source) +3. Add more sub channels (optional) +4. Write Service Info and Multiplex Info in FIB source + +Execute "DABstep" out of your terminal for a more user-friendly graphical application + + + _enabled + True + + + _coordinate + (200, 12) + + + _rotation + 0 + + + id + note_0 + + + note + Instructions: + + + + qtgui_freq_sink_x + + autoscale + False + + + average + 1.0 + + + bw + samp_rate + + + alias + + + + fc + 0 + + + comment + + + + ctrlpanel + False + + + affinity + + + + _enabled + True + + + fftsize + 1024 + + + _coordinate + (1323, 347) + + + gui_hint + + + + _rotation + 0 + + + grid + False + + + id + qtgui_freq_sink_x_0 + + + legend + True + + + alpha1 + 1.0 + + + color1 + "blue" + + + label1 + + + + width1 + 1 + + + alpha10 + 1.0 + + + color10 + "dark blue" + + + label10 + + + + width10 + 1 + + + alpha2 + 1.0 + + + color2 + "red" + + + label2 + + + + width2 + 1 + + + alpha3 + 1.0 + + + color3 + "green" + + + label3 + + + + width3 + 1 + + + alpha4 + 1.0 + + + color4 + "black" + + + label4 + + + + width4 + 1 + + + alpha5 + 1.0 + + + color5 + "cyan" + + + label5 + - minoutbuf - 0 + width5 + 1 - - - dab_msc_encode - alias - + alpha6 + 1.0 - comment - + color6 + "magenta" - affinity + label6 - dab_mode + width6 1 - data_rate_n - 14 + alpha7 + 1.0 - _enabled - True + color7 + "yellow" - _coordinate - (912, 471) + label7 + - _rotation - 0 + width7 + 1 - id - dab_msc_encode_0 + alpha8 + 1.0 - maxoutbuf - 0 + color8 + "dark red" - minoutbuf - 0 + label8 + - protection - 2 + width8 + 1 - samp_rate - samp_rate + alpha9 + 1.0 - - - dab_ofdm_mod - alias - + color9 + "dark green" - comment + label9 - affinity - + width9 + 1 - dab_mode - 1 + maxoutbuf + 0 - _enabled - True + minoutbuf + 0 - _coordinate - (880, 233) + name + "" - _rotation - 0 + nconnections + 1 - id - dab_ofdm_mod_0 + showports + True - maxoutbuf - 0 + freqhalf + True - minoutbuf + tr_chan 0 - samp_rate - samp_rate + tr_level + 0.0 - - - note - alias - + tr_mode + qtgui.TRIG_MODE_FREE - comment - 1. Set frequency in USRP -2. Choose audio source (.wav file or audio source) -3. Add more sub channels (optional) -4. Write Service Info and Multiplex Info in FIB source + tr_tag + "" - _enabled - True + type + complex - _coordinate - (200, 12) + update_time + 0.10 - _rotation - 0 + wintype + firdes.WIN_BLACKMAN_hARRIS - id - note_0 + ymax + 10 - note - Instructions: + ymin + -140 - qtgui_freq_sink_x + qtgui_time_sink_x autoscale False - - average - 1.0 - - - bw - samp_rate - alias - - fc - 0 - comment @@ -758,16 +1255,16 @@ - _enabled + entags True - fftsize - 1024 + _enabled + True _coordinate - (1104, 110) + (1324, 428) gui_hint @@ -783,7 +1280,7 @@ id - qtgui_freq_sink_x_0 + qtgui_time_sink_x_0 legend @@ -801,6 +1298,14 @@ label1 + + marker1 + -1 + + + style1 + 1 + width1 1 @@ -811,12 +1316,20 @@ color10 - "dark blue" + "blue" label10 + + marker10 + -1 + + + style10 + 1 + width10 1 @@ -833,6 +1346,14 @@ label2 + + marker2 + -1 + + + style2 + 1 + width2 1 @@ -849,6 +1370,14 @@ label3 + + marker3 + -1 + + + style3 + 1 + width3 1 @@ -865,6 +1394,14 @@ label4 + + marker4 + -1 + + + style4 + 1 + width4 1 @@ -881,6 +1418,14 @@ label5 + + marker5 + -1 + + + style5 + 1 + width5 1 @@ -897,6 +1442,14 @@ label6 + + marker6 + -1 + + + style6 + 1 + width6 1 @@ -913,6 +1466,14 @@ label7 + + marker7 + -1 + + + style7 + 1 + width7 1 @@ -929,6 +1490,14 @@ label8 + + marker8 + -1 + + + style8 + 1 + width8 1 @@ -946,16 +1515,16 @@ - width9 - 1 + marker9 + -1 - maxoutbuf - 0 + style9 + 1 - minoutbuf - 0 + width9 + 1 name @@ -966,17 +1535,21 @@ 1 - showports - True + size + 1024 - freqhalf - True + srate + samp_rate tr_chan 0 + + tr_delay + 0 + tr_level 0.0 @@ -985,6 +1558,10 @@ tr_mode qtgui.TRIG_MODE_FREE + + tr_slope + qtgui.TRIG_SLOPE_POS + tr_tag "" @@ -998,16 +1575,20 @@ 0.10 - wintype - firdes.WIN_BLACKMAN_hARRIS + ylabel + Amplitude + + + yunit + "" ymax - 10 + 1 ymin - -140 + -1 @@ -1030,7 +1611,7 @@ _coordinate - (672, 492) + (648, 492) _rotation @@ -1069,7 +1650,7 @@ center_freq0 - 208064000 + uhd.tune_request(freq, 2*samp_rate) norm_gain0 @@ -1077,7 +1658,7 @@ gain0 - 50 + gain_range ant10 @@ -1701,7 +2282,7 @@ clock_rate - 0.0 + 8*samp_rate comment @@ -1721,11 +2302,11 @@ _enabled - True + 1 _coordinate - (1096, 200) + (1316, 187) _rotation @@ -1741,7 +2322,7 @@ clock_source0 - + external sd_spec0 @@ -1749,7 +2330,7 @@ time_source0 - + external clock_source1 @@ -1884,6 +2465,24 @@ 0 1 + + blocks_multiply_const_vxx_0 + qtgui_freq_sink_x_0 + 0 + 0 + + + blocks_multiply_const_vxx_0 + qtgui_time_sink_x_0 + 0 + 0 + + + blocks_multiply_const_vxx_0 + uhd_usrp_sink_0 + 0 + 0 + blocks_stream_to_vector_0 dab_ofdm_mod_0 @@ -1940,13 +2539,7 @@ dab_ofdm_mod_0 - qtgui_freq_sink_x_0 - 0 - 0 - - - dab_ofdm_mod_0 - uhd_usrp_sink_0 + blocks_multiply_const_vxx_0 0 0 diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index cd79e04b..ab3b498d 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -17,33 +17,13 @@ # the Free Software Foundation, Inc., 51 Franklin Street, # Boston, MA 02110-1301, USA. install(FILES - dab_ofdm_sync_dab.xml - dab_ofdm_sync_dab2.xml - dab_detect_null.xml - dab_moving_sum_ff.xml - dab_ofdm_ffe_all_in_one.xml - dab_ofdm_sampler.xml - dab_ofdm_coarse_frequency_correct.xml dab_diff_phasor_vcc.xml - dab_ofdm_remove_first_symbol_vcc.xml -# dab_frequency_interleaver_vcc.xml - dab_qpsk_demapper_vcb.xml + dab_frequency_interleaver_vcc.xml dab_complex_to_interleaved_float_vcf.xml - dab_modulo_ff.xml - dab_measure_processing_rate.xml - dab_fic_decode.xml - dab_ofdm_demod.xml dab_ofdm_mod.xml - dab_select_vectors.xml - dab_repartition_vectors.xml -# dab_unpuncture_vff.xml - dab_prune_vectors.xml + dab_unpuncture_vff.xml dab_fib_sink_vb.xml - dab_estimate_sample_rate_bf.xml - dab_fractional_interpolator_triggered_update_cc.xml - dab_magnitude_equalizer_vcc.xml - dab_qpsk_mapper_vbc.xml -# dab_ofdm_insert_pilot_vcc.xml + dab_ofdm_insert_pilot_vcc.xml dab_sum_phasor_trig_vcc.xml dab_ofdm_move_and_insert_zero.xml dab_insert_null_symbol.xml @@ -52,8 +32,6 @@ install(FILES dab_crc16_bb.xml dab_msc_decode.xml dab_fib_source_b.xml - dab_select_subch_vfvf.xml - dab_unpuncture_ff.xml dab_prune.xml dab_firecode_check_bb.xml dab_fic_encode.xml @@ -62,7 +40,6 @@ install(FILES dab_dab_transmission_frame_mux_bb.xml dab_transmitter_c.xml dab_conv_encoder_bb.xml - dab_mapper_bc.xml dab_mp2_decode_bs.xml dab_mp4_decode_bs.xml dab_reed_solomon_decode_bb.xml @@ -71,5 +48,11 @@ install(FILES dab_mp4_encode_sb.xml dab_mp2_encode_sb.xml dab_valve_ff.xml - dab_peak_detector_fb.xml DESTINATION share/gnuradio/grc/blocks + dab_ofdm_synchronization_cvf.xml + dab_ofdm_coarse_frequency_correction_vcvc.xml + dab_demux_cc.xml + dab_ofdm_demod_cc.xml + dab_fic_decode_vc.xml + dab_select_cus_vfvf.xml + dab_qpsk_mapper_vbvc.xml DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/dab_complex_to_interleaved_float_vcf.xml b/grc/dab_complex_to_interleaved_float_vcf.xml index a4674f63..33bd686a 100644 --- a/grc/dab_complex_to_interleaved_float_vcf.xml +++ b/grc/dab_complex_to_interleaved_float_vcf.xml @@ -1,5 +1,5 @@ - Complex to interleaved float + Complex to interleaved float vcf dab_complex_to_interleaved_float_vcf [DAB] import dab diff --git a/grc/dab_dabplus_audio_decoder_ff.xml b/grc/dab_dabplus_audio_decoder_ff.xml index f87d34f9..157d9f1b 100644 --- a/grc/dab_dabplus_audio_decoder_ff.xml +++ b/grc/dab_dabplus_audio_decoder_ff.xml @@ -75,14 +75,10 @@ - dat + MSC complex 1536 - - sync - byte - audio_left float diff --git a/grc/dab_demux_cc.xml b/grc/dab_demux_cc.xml new file mode 100644 index 00000000..3aefbaed --- /dev/null +++ b/grc/dab_demux_cc.xml @@ -0,0 +1,43 @@ + + + DAB: Demux + dab_demux_cc + [DAB] + import dab + dab.demux_cc($symbol_length, $symbols_fic, $symbols_msc, $fillval) + + Symbol Length + symbol_length + int + + + Symbols FIC + symbols_fic + int + + + Symbol MSC + symbols_msc + int + + + Fillvalue + fillval + complex + + + in + complex + $symbol_length + + + FIC + complex + $symbol_length + + + MSC + complex + $symbol_length + + diff --git a/grc/dab_detect_null.xml b/grc/dab_detect_null.xml deleted file mode 100644 index adf206ef..00000000 --- a/grc/dab_detect_null.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - Detect NULL - dab_detect_null - [DAB] - import dab - dab.detect_null($length, False) - - NULL Len. in samples - length - int - - - - in - complex - - - - out - byte - - diff --git a/grc/dab_estimate_sample_rate_bf.xml b/grc/dab_estimate_sample_rate_bf.xml deleted file mode 100644 index 52cb8281..00000000 --- a/grc/dab_estimate_sample_rate_bf.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - DAB Est Samp Rate - estimate_sample_rate_bf - [DAB] - import dab - dab.estimate_sample_rate_bf($exp_samp_rate, $frame_length) - - Samp. Rate - exp_samp_rate - samp_rate - int - - - Frame Len. - frame_length - int - - - in - byte - - - out - float - - diff --git a/grc/dab_fib_source_b.xml b/grc/dab_fib_source_b.xml index 4a25fef6..89979f05 100644 --- a/grc/dab_fib_source_b.xml +++ b/grc/dab_fib_source_b.xml @@ -3,11 +3,10 @@ dab_fib_source_b [DAB] import dab - dab.fib_source_b($dab_mode, $num_subch, $ensemble_label, $programme_service_labels, $service_comp_label, $service_comp_lang, $protection_mode, $data_rate_n) - - DAB Mode - dab_mode - 1 + dab.fib_source_b($transmission_mode, $coutry_ID, $num_subch, $ensemble_label, $programme_service_labels, "", $service_comp_lang, $protection_mode, $data_rate_n, $dabplus) + + Mode + transmission_mode int + + + - subchannel address + Sampling Rate + samp_rate + samp_rate + int + + + Subchannel address address int @@ -68,12 +91,9 @@ - data - float - - - trigger - byte + MSC symbols + complex + 1536 out diff --git a/grc/dab_ofdm_coarse_frequency_correct.xml b/grc/dab_ofdm_coarse_frequency_correct.xml deleted file mode 100644 index 57951584..00000000 --- a/grc/dab_ofdm_coarse_frequency_correct.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - OFDM coarse freq. corr. - dab_ofdm_coarse_frequency_correct - [DAB] - import dab - dab.ofdm_coarse_frequency_correct($fft_length, $num_carriers, $cp_length) - - - Length - fft_length - int - - - - Carriers - num_carriers - int - - - - CP Len - cp_length - int - - - - - in - complex - $fft_length - - - - sync - byte - - - - - out - complex - $num_carriers - - - - sync - byte - - diff --git a/grc/dab_ofdm_coarse_frequency_correction_vcvc.xml b/grc/dab_ofdm_coarse_frequency_correction_vcvc.xml new file mode 100644 index 00000000..b47ee58e --- /dev/null +++ b/grc/dab_ofdm_coarse_frequency_correction_vcvc.xml @@ -0,0 +1,32 @@ + + DAB: Coarse Frequency Correction + dab_ofdm_coarse_frequency_correction_vcvc + [DAB] + import dab + dab.ofdm_coarse_frequency_correction_vcvc($fft_length, $num_carriers, $cyclic_prefix_length) + + Fft_length + fft_length + int + + + Num_carriers + num_carriers + int + + + Cyclic_prefix_length + cyclic_prefix_length + int + + + in + complex + $fft_length + + + out + complex + $num_carriers + + diff --git a/grc/dab_ofdm_demod.xml b/grc/dab_ofdm_demod.xml deleted file mode 100644 index 0619753d..00000000 --- a/grc/dab_ofdm_demod.xml +++ /dev/null @@ -1,160 +0,0 @@ - - - DAB: OFDM Demodulator - dab_ofdm_demod - [DAB] - import dab - dab.ofdm_demod( - dab.parameters.dab_parameters( - mode=$dab_mode, - sample_rate=$samp_rate, - verbose=False - ), - dab.parameters.receiver_parameters( - mode=$dab_mode, - softbits=$soft_bits.soft, - input_fft_filter=$input_fft, - autocorrect_sample_rate=$autocorr_sr, - sample_rate_correction_factor=1, - verbose=False, - correct_ffe=$correct_ffe, - equalize_magnitude=$eq_mag - ) - ) - - - DAB Mode - dab_mode - 1 - enum - - - - - - - Sampling Rate - samp_rate - samp_rate - int - - - - Input FFT Filter - input_fft - True - enum - - - - - - Auto-corr. samplerate - autocorr_sr - True - enum - - - - - - Fine-Freq. corr. - correct_ffe - True - enum - - - - - - Equalize Magnitude - eq_mag - True - enum - - - - - - Soft Bits - soft_bits - soft - enum - - - - 1 <= $dab_mode <= 4 - - in - complex - - - dat - $soft_bits.type - $dab_mode.vlensize / $soft_bits.vlenfrac - - - sync - byte - - - Demodulates a whole DAB signal. - Output vector size depends on selected mode: - Mode I: 1536 complex samples or 384 bytes - Mode II: 384 complex samples or 96 bytes - Mode III: 192 complex samples or 48 bytes - Mode IV: 768 complex samples or 192 bytes - - diff --git a/grc/dab_ofdm_demod_cc.xml b/grc/dab_ofdm_demod_cc.xml new file mode 100644 index 00000000..9ded75b8 --- /dev/null +++ b/grc/dab_ofdm_demod_cc.xml @@ -0,0 +1,69 @@ + + + DAB: OFDM Demodulator + dab_ofdm_demod_cc + [DAB] + import dab + dab.ofdm_demod_cc( + dab.parameters.dab_parameters( + mode=$dab_mode, + sample_rate=$samp_rate, + verbose=False + ) + ) + + + DAB Mode + dab_mode + 1 + enum + + + + + + + Sampling Rate + samp_rate + samp_rate + int + + + IQ samples + complex + + + FIC + complex + 1536 + + + MSC + complex + 1536 + + + Demodulates a whole DAB signal. + Output vector size depends on selected mode: + Mode I: 1536 complex samples or 384 bytes + Mode II: 384 complex samples or 96 bytes + Mode III: 192 complex samples or 48 bytes + Mode IV: 768 complex samples or 192 bytes + + diff --git a/grc/dab_ofdm_ffe_all_in_one.xml b/grc/dab_ofdm_ffe_all_in_one.xml deleted file mode 100644 index bfcd2481..00000000 --- a/grc/dab_ofdm_ffe_all_in_one.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - OFDM ffe all in one - dab_ofdm_ffe_all_in_one - [DAB] - import dab - dab.ofdm_ffe_all_in_one($symbol_length, $fft_length, $num_symbols, $alpha, $sample_rate) - - Symbol length - symbol_length - int - - - FFT length - fft_length - int - - - Number of symbols - num_symbols - int - - - alpha - alpha - real - - - Sample rate - sample_rate - int - - - - - in - complex - - - in - byte - - - - - out - float - - diff --git a/grc/dab_ofdm_remove_first_symbol_vcc.xml b/grc/dab_ofdm_remove_first_symbol_vcc.xml deleted file mode 100644 index 1e4acef4..00000000 --- a/grc/dab_ofdm_remove_first_symbol_vcc.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - OFDM Remove First Symbol - dab_ofdm_remove_first_symbol_vcc - [DAB] - import dab - dab.ofdm_remove_first_symbol_vcc($num_carriers) - - Num Carriers - num_carriers - int - - - - in - complex - $num_carriers - - - sync - byte - - - - out - complex - $num_carriers - - - sync - byte - - diff --git a/grc/dab_ofdm_sampler.xml b/grc/dab_ofdm_sampler.xml deleted file mode 100644 index a08b00db..00000000 --- a/grc/dab_ofdm_sampler.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - OFDM Sampler - dab_ofdm_sampler - [DAB] - import dab - dab.ofdm_sampler($fft_length, $cp_length, $symbols_per_frame, $gap) - - - fft_length - fft_length - int - - - cp_length - cp_length - int - - - symbols_per_frame - symbols_per_frame - int - - - gap - gap - int - - - - in - complex - - - sync - byte - - - - - out - complex - $fft_length - - - sync - byte - - diff --git a/grc/dab_ofdm_sync_dab.xml b/grc/dab_ofdm_sync_dab.xml deleted file mode 100644 index 6ca4bcc3..00000000 --- a/grc/dab_ofdm_sync_dab.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - ofdm_sync_dab - dab_ofdm_sync_dab - dab - import dab - dab.ofdm_sync_dab($dab_params, $rx_params, $debug) - - - ... - ... - ... - - - - - in - - - - - - out - - - diff --git a/grc/dab_ofdm_sync_dab2.xml b/grc/dab_ofdm_sync_dab2.xml deleted file mode 100644 index 320cbd73..00000000 --- a/grc/dab_ofdm_sync_dab2.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - OFDM sync v2 - dab_ofdm_sync_dab2 - [DAB] - import dab - dab.ofdm_sync_dab2($dab_params, $rx_params, $debug) - - Mode - mode - int - - - in - complex - - - out - complex - - - trigger - byte - - diff --git a/grc/dab_ofdm_synchronization_cvf.xml b/grc/dab_ofdm_synchronization_cvf.xml new file mode 100644 index 00000000..84a47156 --- /dev/null +++ b/grc/dab_ofdm_synchronization_cvf.xml @@ -0,0 +1,35 @@ + + DAB: Synchronization + dab_ofdm_synchronization_cvf + [DAB] + import dab + dab.ofdm_synchronization_cvf($symbol_length, $cyclic_prefix_length, $fft_length, $symbols_per_frame) + + Symbol_length + symbol_length + int + + + Cyclic_prefix_length + cyclic_prefix_length + int + + + Fft_length + fft_length + int + + + Symbols_per_frame + symbols_per_frame + int + + + in + complex + + + out + complex + + diff --git a/grc/dab_peak_detector_fb.xml b/grc/dab_peak_detector_fb.xml deleted file mode 100644 index 545eb18b..00000000 --- a/grc/dab_peak_detector_fb.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - peak_detector_fb - dab_peak_detector_fb - dab - import dab - dab.peak_detector_fb($threshold_factor_rise, $threshold_factor_fall, $look_ahead, $alpha) - - TH Factor Rise - threshold_factor_rise - 0.25 - real - - - TH Factor Fall - threshold_factor_fall - 0.40 - real - - - Look Ahead - look_ahead - 10 - int - - - Alpha - alpha - 0.001 - real - - - in - float - - - out - byte - - diff --git a/grc/dab_prune_vectors.xml b/grc/dab_prune_vectors.xml deleted file mode 100644 index 85f700ec..00000000 --- a/grc/dab_prune_vectors.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - prune_vectors - dab_prune_vectors - dab - import dab - dab.prune_vectors($itemsize, $length, $prune_start, $prune_end) - - - ... - ... - ... - - - - - in - - - - - - out - - - diff --git a/grc/dab_qpsk_demapper_vcb.xml b/grc/dab_qpsk_demapper_vcb.xml deleted file mode 100644 index 10bf011a..00000000 --- a/grc/dab_qpsk_demapper_vcb.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - qpsk_demapper_vcb - dab_qpsk_demapper_vcb - dab - import dab - dab.qpsk_demapper_vcb($symbol_length) - - - ... - ... - ... - - - - - in - - - - - - out - - - diff --git a/grc/dab_qpsk_mapper_vbc.xml b/grc/dab_qpsk_mapper_vbc.xml deleted file mode 100644 index 44bf6c0d..00000000 --- a/grc/dab_qpsk_mapper_vbc.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - qpsk_mapper_vbc - dab_qpsk_mapper_vbc - dab - import dab - dab.qpsk_mapper_vbc($symbol_length) - - - ... - ... - ... - - - - - in - - - - - - out - - - diff --git a/grc/dab_qpsk_mapper_vbvc.xml b/grc/dab_qpsk_mapper_vbvc.xml new file mode 100644 index 00000000..a6b4576c --- /dev/null +++ b/grc/dab_qpsk_mapper_vbvc.xml @@ -0,0 +1,22 @@ + + Qpsk mapper vbvc + dab_qpsk_mapper_vbvc + DAB + import dab + dab.qpsk_mapper_vbvc($symbol_length) + + Symbol_length + symbol_length + raw + + + in + byte + $symbol_length/4 + + + out + complex + $symbol_length + + diff --git a/grc/dab_reed_solomon_encode_bb.xml b/grc/dab_reed_solomon_encode_bb.xml index 2bb93b15..876a2acf 100644 --- a/grc/dab_reed_solomon_encode_bb.xml +++ b/grc/dab_reed_solomon_encode_bb.xml @@ -1,5 +1,5 @@ - DAB: Reed Solomon Encoder + DAB: RS Encoder reed_solomon_encode_bb [DAB] import dab diff --git a/grc/dab_repartition_vectors.xml b/grc/dab_repartition_vectors.xml deleted file mode 100644 index 9a39f9de..00000000 --- a/grc/dab_repartition_vectors.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - repartition_vectors - dab_repartition_vectors - dab - import dab - dab.repartition_vectors($itemsize, $vlen_in, $vlen_out, $multiply, $divide) - - - ... - ... - ... - - - - - in - - - - - - out - - - diff --git a/grc/dab_select_cus_vfvf.xml b/grc/dab_select_cus_vfvf.xml new file mode 100644 index 00000000..ac1d248b --- /dev/null +++ b/grc/dab_select_cus_vfvf.xml @@ -0,0 +1,37 @@ + + Select CUs + dab_select_cus_vfvf + DAB + import dab + dab.select_cus_vfvf($vlen, $frame_len, $address, $size) + + Vlen + vlen + raw + + + Frame_len + frame_len + raw + + + Address + address + raw + + + Size + size + raw + + + in + float + $vlen + + + out + float + $vlen + + diff --git a/grc/dab_select_subch_vfvf.xml b/grc/dab_select_subch_vfvf.xml deleted file mode 100644 index f096e6a5..00000000 --- a/grc/dab_select_subch_vfvf.xml +++ /dev/null @@ -1,37 +0,0 @@ - - Select subchannel - dab_select_subch_vfvf - [DAB] - import dab - dab.select_subch_vfvf($vlen_in, $vlen_out, $address, $total_size) - - Vector length in - vlen_in - raw - - - Vector length out - vlen_out - raw - - - Address - address - raw - - - Total size - total_size - raw - - - in - float - $vlen_in - - - out - float - $vlen_out - - diff --git a/grc/dab_select_vectors.xml b/grc/dab_select_vectors.xml deleted file mode 100644 index aaf06f0e..00000000 --- a/grc/dab_select_vectors.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - select_vectors - dab_select_vectors - dab - import dab - dab.select_vectors($itemsize, $length, $num_select, $num_skip) - - - ... - ... - ... - - - - - in - - - - - - out - - - diff --git a/grc/dab_unpuncture_ff.xml b/grc/dab_unpuncture_ff.xml deleted file mode 100644 index 78527dc9..00000000 --- a/grc/dab_unpuncture_ff.xml +++ /dev/null @@ -1,25 +0,0 @@ - - Unpuncture - dab_unpuncture_ff - [DAB] - import dab - dab.unpuncture_ff($puncturing_vector, $fillval) - - Puncturing vector - puncturing_vector - raw - - - Fillvalue - fillval - float - - - in - float - - - out - float - - diff --git a/include/dab/CMakeLists.txt b/include/dab/CMakeLists.txt index 50993e5f..066b4283 100644 --- a/include/dab/CMakeLists.txt +++ b/include/dab/CMakeLists.txt @@ -22,26 +22,11 @@ ######################################################################## install(FILES api.h - moving_sum_ff.h - ofdm_ffe_all_in_one.h - ofdm_sampler.h - ofdm_coarse_frequency_correct.h diff_phasor_vcc.h - ofdm_remove_first_symbol_vcc.h frequency_interleaver_vcc.h - qpsk_demapper_vcb.h complex_to_interleaved_float_vcf.h - modulo_ff.h - measure_processing_rate.h - select_vectors.h - repartition_vectors.h unpuncture_vff.h - prune_vectors.h fib_sink_vb.h - estimate_sample_rate_bf.h - fractional_interpolator_triggered_update_cc.h - magnitude_equalizer_vcc.h - qpsk_mapper_vbc.h ofdm_insert_pilot_vcc.h sum_phasor_trig_vcc.h ofdm_move_and_insert_zero.h @@ -50,14 +35,11 @@ install(FILES time_deinterleave_ff.h crc16_bb.h fib_source_b.h - select_subch_vfvf.h - unpuncture_ff.h prune.h firecode_check_bb.h puncture_bb.h dab_transmission_frame_mux_bb.h conv_encoder_bb.h - mapper_bc.h mp2_decode_bs.h mp4_decode_bs.h reed_solomon_decode_bb.h @@ -65,5 +47,9 @@ install(FILES mp4_encode_sb.h mp2_encode_sb.h valve_ff.h - peak_detector_fb.h DESTINATION include/dab + ofdm_synchronization_cvf.h + ofdm_coarse_frequency_correction_vcvc.h + demux_cc.h + select_cus_vfvf.h + qpsk_mapper_vbvc.h DESTINATION include/dab ) diff --git a/include/dab/ofdm_sampler.h b/include/dab/demux_cc.h similarity index 64% rename from include/dab/ofdm_sampler.h rename to include/dab/demux_cc.h index 5219734b..68d43ae2 100644 --- a/include/dab/ofdm_sampler.h +++ b/include/dab/demux_cc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2015 <+YOU OR YOUR COMPANY+>. + * 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 @@ -19,8 +19,8 @@ */ -#ifndef INCLUDED_DAB_OFDM_SAMPLER_H -#define INCLUDED_DAB_OFDM_SAMPLER_H +#ifndef INCLUDED_DAB_DEMUX_CC_H +#define INCLUDED_DAB_DEMUX_CC_H #include #include @@ -33,24 +33,24 @@ namespace gr { * \ingroup dab * */ - class DAB_API ofdm_sampler : virtual public gr::block + class DAB_API demux_cc : virtual public gr::block { public: - typedef boost::shared_ptr sptr; + typedef boost::shared_ptr sptr; /*! - * \brief Return a shared_ptr to a new instance of dab::ofdm_sampler. + * \brief Return a shared_ptr to a new instance of dab::demux_cc. * - * To avoid accidental use of raw pointers, dab::ofdm_sampler's + * To avoid accidental use of raw pointers, dab::demux_cc's * constructor is in a private implementation - * class. dab::ofdm_sampler::make is the public interface for + * class. dab::demux_cc::make is the public interface for * creating new instances. */ - static sptr make(unsigned int fft_length, unsigned int cp_length, unsigned int symbols_per_frame,unsigned int gap); + static sptr make(unsigned int symbol_length, unsigned int symbols_fic, unsigned int symbol_msc, gr_complex fillval = gr_complex(0,0)); }; } // namespace dab } // namespace gr -#endif /* INCLUDED_DAB_OFDM_SAMPLER_H */ +#endif /* INCLUDED_DAB_DEMUX_CC_H */ diff --git a/include/dab/estimate_sample_rate_bf.h b/include/dab/estimate_sample_rate_bf.h deleted file mode 100644 index e4179f02..00000000 --- a/include/dab/estimate_sample_rate_bf.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2015 <+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_DAB_ESTIMATE_SAMPLE_RATE_BF_H -#define INCLUDED_DAB_ESTIMATE_SAMPLE_RATE_BF_H - -#include -#include - -namespace gr { - namespace dab { - - /*! - * \brief <+description of block+> - * \ingroup dab - * - */ - class DAB_API estimate_sample_rate_bf : virtual public gr::sync_block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::estimate_sample_rate_bf. - * - * To avoid accidental use of raw pointers, dab::estimate_sample_rate_bf's - * constructor is in a private implementation - * class. dab::estimate_sample_rate_bf::make is the public interface for - * creating new instances. - */ - static sptr make(float expected_sample_rate, int frame_length); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_ESTIMATE_SAMPLE_RATE_BF_H */ - diff --git a/include/dab/fractional_interpolator_triggered_update_cc.h b/include/dab/fractional_interpolator_triggered_update_cc.h deleted file mode 100644 index 8c3671eb..00000000 --- a/include/dab/fractional_interpolator_triggered_update_cc.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2015 <+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_DAB_FRACTIONAL_INTERPOLATOR_TRIGGERED_UPDATE_CC_H -#define INCLUDED_DAB_FRACTIONAL_INTERPOLATOR_TRIGGERED_UPDATE_CC_H - -#include -#include - -namespace gr { - namespace dab { - - /*! - * \brief <+description of block+> - * \ingroup dab - * - */ - class DAB_API fractional_interpolator_triggered_update_cc : virtual public gr::block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::fractional_interpolator_triggered_update_cc. - * - * To avoid accidental use of raw pointers, dab::fractional_interpolator_triggered_update_cc's - * constructor is in a private implementation - * class. dab::fractional_interpolator_triggered_update_cc::make is the public interface for - * creating new instances. - */ - static sptr make(float phase_shift, float interp_ratio); - - virtual void set_interp_ratio (float interp_ratio) = 0; - - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_FRACTIONAL_INTERPOLATOR_TRIGGERED_UPDATE_CC_H */ - diff --git a/include/dab/magnitude_equalizer_vcc.h b/include/dab/magnitude_equalizer_vcc.h deleted file mode 100644 index 83df1e6c..00000000 --- a/include/dab/magnitude_equalizer_vcc.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2015 <+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_DAB_MAGNITUDE_EQUALIZER_VCC_H -#define INCLUDED_DAB_MAGNITUDE_EQUALIZER_VCC_H - -#include -#include - -namespace gr { - namespace dab { - - /*! - * \brief <+description of block+> - * \ingroup dab - * - */ - class DAB_API magnitude_equalizer_vcc : virtual public gr::sync_block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::magnitude_equalizer_vcc. - * - * To avoid accidental use of raw pointers, dab::magnitude_equalizer_vcc's - * constructor is in a private implementation - * class. dab::magnitude_equalizer_vcc::make is the public interface for - * creating new instances. - */ - static sptr make(unsigned int vlen, unsigned int num_symbols); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_MAGNITUDE_EQUALIZER_VCC_H */ - diff --git a/include/dab/mapper_bc.h b/include/dab/mapper_bc.h deleted file mode 100644 index 06c71007..00000000 --- a/include/dab/mapper_bc.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2017 by Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). - * - * 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_DAB_MAPPER_BC_H -#define INCLUDED_DAB_MAPPER_BC_H - -#include -#include - -namespace gr { - namespace dab { - - /*! \brief QPSK mapper according to the DAB standard ETSI EN 300 401 V1.4.1, clause 14.5 - - * \ingroup dab - * - */ - class DAB_API mapper_bc : virtual public gr::block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::mapper_bc. - * - * To avoid accidental use of raw pointers, dab::mapper_bc's - * constructor is in a private implementation - * class. dab::mapper_bc::make is the public interface for - * creating new instances. - */ - static sptr make(int symbol_length); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_MAPPER_BC_H */ - diff --git a/include/dab/measure_processing_rate.h b/include/dab/measure_processing_rate.h deleted file mode 100644 index 4003df9d..00000000 --- a/include/dab/measure_processing_rate.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2015 <+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_DAB_MEASURE_PROCESSING_RATE_H -#define INCLUDED_DAB_MEASURE_PROCESSING_RATE_H - -#include -#include - -namespace gr { - namespace dab { - - /*! - * \brief <+description of block+> - * \ingroup dab - * - */ - class DAB_API measure_processing_rate : virtual public gr::sync_block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::measure_processing_rate. - * - * To avoid accidental use of raw pointers, dab::measure_processing_rate's - * constructor is in a private implementation - * class. dab::measure_processing_rate::make is the public interface for - * creating new instances. - */ - static sptr make(size_t itemsize, int samples_to_count); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_MEASURE_PROCESSING_RATE_H */ - diff --git a/include/dab/modulo_ff.h b/include/dab/modulo_ff.h deleted file mode 100644 index 26695020..00000000 --- a/include/dab/modulo_ff.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2015 <+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_DAB_MODULO_FF_H -#define INCLUDED_DAB_MODULO_FF_H - -#include -#include - -namespace gr { - namespace dab { - - /*! - * \brief <+description of block+> - * \ingroup dab - * - */ - class DAB_API modulo_ff : virtual public gr::sync_block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::modulo_ff. - * - * To avoid accidental use of raw pointers, dab::modulo_ff's - * constructor is in a private implementation - * class. dab::modulo_ff::make is the public interface for - * creating new instances. - */ - static sptr make(float div); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_MODULO_FF_H */ - diff --git a/include/dab/moving_sum_ff.h b/include/dab/moving_sum_ff.h deleted file mode 100644 index b3338a3f..00000000 --- a/include/dab/moving_sum_ff.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2015 <+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_DAB_MOVING_SUM_FF_H -#define INCLUDED_DAB_MOVING_SUM_FF_H - -#include -#include - -namespace gr { - namespace dab { - - /*! - * \brief <+description of block+> - * \ingroup dab - * - */ - class DAB_API moving_sum_ff : virtual public gr::sync_block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::moving_sum_ff. - * - * To avoid accidental use of raw pointers, dab::moving_sum_ff's - * constructor is in a private implementation - * class. dab::moving_sum_ff::make is the public interface for - * creating new instances. - */ - static sptr make(int length); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_MOVING_SUM_FF_H */ - diff --git a/include/dab/ofdm_coarse_frequency_correct.h b/include/dab/ofdm_coarse_frequency_correct.h deleted file mode 100644 index 0c90bc2b..00000000 --- a/include/dab/ofdm_coarse_frequency_correct.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2015 <+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_DAB_OFDM_COARSE_FREQUENCY_CORRECT_H -#define INCLUDED_DAB_OFDM_COARSE_FREQUENCY_CORRECT_H - -#include -#include - -namespace gr { - namespace dab { - - /*! - * \brief <+description of block+> - * \ingroup dab - * - */ - class DAB_API ofdm_coarse_frequency_correct : virtual public gr::sync_block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::ofdm_coarse_frequency_correct. - * - * To avoid accidental use of raw pointers, dab::ofdm_coarse_frequency_correct's - * constructor is in a private implementation - * class. dab::ofdm_coarse_frequency_correct::make is the public interface for - * creating new instances. - */ - static sptr make(unsigned int fft_length, unsigned int num_carriers, unsigned int cp_length); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_OFDM_COARSE_FREQUENCY_CORRECT_H */ - diff --git a/include/dab/ofdm_coarse_frequency_correction_vcvc.h b/include/dab/ofdm_coarse_frequency_correction_vcvc.h new file mode 100644 index 00000000..69928f4c --- /dev/null +++ b/include/dab/ofdm_coarse_frequency_correction_vcvc.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * 2018 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * The content of this class is adopted from ODR-DabMod and written into a GNU Radio OutOfTree block. + * + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty + the Queen in Right of Canada (Communications Research Center Canada) + See https://github.com/Opendigitalradio/ODR-DabMod for licensing information of ODR-DabMod. + * + * 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_DAB_OFDM_COARSE_FREQUENCY_CORRECTION_VCVC_H +#define INCLUDED_DAB_OFDM_COARSE_FREQUENCY_CORRECTION_VCVC_H + +#include +#include + +namespace gr { + namespace dab { + + /*! + * \brief coarse frequency correction in mulitple of the sub-carrier spacing + * \ingroup dab + * + */ + class DAB_API ofdm_coarse_frequency_correction_vcvc : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr sptr; + + virtual float get_snr() = 0; + + /*! + * \brief Return a shared_ptr to a new instance of dab::ofdm_coarse_frequency_correction_vcvc. + * + * To avoid accidental use of raw pointers, dab::ofdm_coarse_frequency_correction_vcvc's + * constructor is in a private implementation + * class. dab::ofdm_coarse_frequency_correction_vcvc::make is the public interface for + * creating new instances. + */ + static sptr make(int fft_length, int num_carriers, int cyclic_prefix_length); + }; + + } // namespace dab +} // namespace gr + +#endif /* INCLUDED_DAB_OFDM_COARSE_FREQUENCY_CORRECTION_VCVC_H */ + diff --git a/include/dab/ofdm_ffe_all_in_one.h b/include/dab/ofdm_ffe_all_in_one.h deleted file mode 100644 index a124ac75..00000000 --- a/include/dab/ofdm_ffe_all_in_one.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2015 <+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_DAB_OFDM_FFE_ALL_IN_ONE_H -#define INCLUDED_DAB_OFDM_FFE_ALL_IN_ONE_H - -#include -#include - -namespace gr { - namespace dab { - - /*! - * \brief <+description of block+> - * \ingroup dab - * - */ - class DAB_API ofdm_ffe_all_in_one : virtual public gr::sync_block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::ofdm_ffe_all_in_one. - * - * To avoid accidental use of raw pointers, dab::ofdm_ffe_all_in_one's - * constructor is in a private implementation - * class. dab::ofdm_ffe_all_in_one::make is the public interface for - * creating new instances. - */ - static sptr make(unsigned int symbol_length, unsigned int fft_length, unsigned int num_symbols, float alpha, unsigned int sample_rate); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_OFDM_FFE_ALL_IN_ONE_H */ - diff --git a/include/dab/ofdm_remove_first_symbol_vcc.h b/include/dab/ofdm_synchronization_cvf.h similarity index 50% rename from include/dab/ofdm_remove_first_symbol_vcc.h rename to include/dab/ofdm_synchronization_cvf.h index 50be141f..1445f3c6 100644 --- a/include/dab/ofdm_remove_first_symbol_vcc.h +++ b/include/dab/ofdm_synchronization_cvf.h @@ -1,6 +1,11 @@ /* -*- c++ -*- */ /* - * Copyright 2015 <+YOU OR YOUR COMPANY+>. + * 2018 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * The content of this class is adopted from ODR-DabMod and written into a GNU Radio OutOfTree block. + * + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty + the Queen in Right of Canada (Communications Research Center Canada) + See https://github.com/Opendigitalradio/ODR-DabMod for licensing information of ODR-DabMod. * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +24,8 @@ */ -#ifndef INCLUDED_DAB_OFDM_REMOVE_FIRST_SYMBOL_VCC_H -#define INCLUDED_DAB_OFDM_REMOVE_FIRST_SYMBOL_VCC_H +#ifndef INCLUDED_DAB_OFDM_SYNCHRONIZATION_CVF_H +#define INCLUDED_DAB_OFDM_SYNCHRONIZATION_CVF_H #include #include @@ -29,28 +34,28 @@ namespace gr { namespace dab { /*! - * \brief <+description of block+> + * \brief fine time and frequency offset measurement and correction * \ingroup dab * */ - class DAB_API ofdm_remove_first_symbol_vcc : virtual public gr::block + class DAB_API ofdm_synchronization_cvf : virtual public gr::block { public: - typedef boost::shared_ptr sptr; + typedef boost::shared_ptr sptr; /*! - * \brief Return a shared_ptr to a new instance of dab::ofdm_remove_first_symbol_vcc. + * \brief Return a shared_ptr to a new instance of dab::ofdm_synchronization_cvf. * - * To avoid accidental use of raw pointers, dab::ofdm_remove_first_symbol_vcc's + * To avoid accidental use of raw pointers, dab::ofdm_synchronization_cvf's * constructor is in a private implementation - * class. dab::ofdm_remove_first_symbol_vcc::make is the public interface for + * class. dab::ofdm_synchronization_cvf::make is the public interface for * creating new instances. */ - static sptr make(unsigned int vlen); + static sptr make(int symbol_length, int cyclic_prefix_lenght, int fft_length, int symbols_per_frame); }; } // namespace dab } // namespace gr -#endif /* INCLUDED_DAB_OFDM_REMOVE_FIRST_SYMBOL_VCC_H */ +#endif /* INCLUDED_DAB_OFDM_SYNCHRONIZATION_CVF_H */ diff --git a/include/dab/peak_detector_fb.h b/include/dab/peak_detector_fb.h deleted file mode 100644 index 8d9e76b8..00000000 --- a/include/dab/peak_detector_fb.h +++ /dev/null @@ -1,115 +0,0 @@ -/* -*- 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_DAB_PEAK_DETECTOR_FB_H -#define INCLUDED_DAB_PEAK_DETECTOR_FB_H - -#include -#include - -namespace gr { - namespace dab { - - /*! - * \brief Detect the peak of a signal - * \ingroup peak_detectors_blk - * - * \details - * If a peak is detected, this block outputs a 1, - * or it outputs 0's. - */ - class DAB_API peak_detector_fb : virtual public gr::sync_block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * Make a peak detector block. - * - * \param threshold_factor_rise The threshold factor determins - * when a peak has started. An average of the signal is - * calculated and when the value of the signal goes over - * threshold_factor_rise*average, we start looking for a - * peak. - * \param threshold_factor_fall The threshold factor determins - * when a peak has ended. An average of the signal is - * calculated and when the value of the signal goes - * below threshold_factor_fall*average, we stop looking - * for a peak. - * \param look_ahead The look-ahead value is used when the - * threshold is found to look if there another peak - * within this step range. If there is a larger value, - * we set that as the peak and look ahead again. This is - * continued until the highest point is found with This - * look-ahead range. - * \param alpha The gain value of a moving average filter - */ - static sptr make(float threshold_factor_rise = 0.25, - float threshold_factor_fall = 0.40, - int look_ahead = 10, - float alpha = 0.001); - - /*! \brief Set the threshold factor value for the rise time - * \param thr new threshold factor - */ - virtual void set_threshold_factor_rise(float thr) = 0; - - /*! \brief Set the threshold factor value for the fall time - * \param thr new threshold factor - */ - virtual void set_threshold_factor_fall(float thr) = 0; - - /*! \brief Set the look-ahead factor - * \param look new look-ahead factor - */ - virtual void set_look_ahead(int look) = 0; - - /*! \brief Set the running average alpha - * \param alpha new alpha for running average - */ - virtual void set_alpha(float alpha) = 0; - - /*! \brief Get the threshold factor value for the rise time - * \return threshold factor - */ - virtual float threshold_factor_rise() = 0; - - /*! \brief Get the threshold factor value for the fall time - * \return threshold factor - */ - virtual float threshold_factor_fall() = 0; - - /*! \brief Get the look-ahead factor value - * \return look-ahead factor - */ - virtual int look_ahead() = 0; - - /*! \brief Get the alpha value of the running average - * \return alpha - */ - virtual float alpha() = 0; - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_PEAK_DETECTOR_FB_H */ - diff --git a/include/dab/prune_vectors.h b/include/dab/prune_vectors.h deleted file mode 100644 index a43c63b5..00000000 --- a/include/dab/prune_vectors.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2015 <+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_DAB_PRUNE_VECTORS_H -#define INCLUDED_DAB_PRUNE_VECTORS_H - -#include -#include - -namespace gr { - namespace dab { - - /*! - * \brief <+description of block+> - * \ingroup dab - * - */ - class DAB_API prune_vectors : virtual public gr::sync_block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::prune_vectors. - * - * To avoid accidental use of raw pointers, dab::prune_vectors's - * constructor is in a private implementation - * class. dab::prune_vectors::make is the public interface for - * creating new instances. - */ - static sptr make(size_t itemsize, unsigned int length, unsigned int prune_start, unsigned int prune_end); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_PRUNE_VECTORS_H */ - diff --git a/include/dab/qpsk_demapper_vcb.h b/include/dab/qpsk_demapper_vcb.h deleted file mode 100644 index 371112fc..00000000 --- a/include/dab/qpsk_demapper_vcb.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2015 <+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_DAB_QPSK_DEMAPPER_VCB_H -#define INCLUDED_DAB_QPSK_DEMAPPER_VCB_H - -#include -#include - -namespace gr { - namespace dab { - - /*! - * \brief <+description of block+> - * \ingroup dab - * - */ - class DAB_API qpsk_demapper_vcb : virtual public gr::sync_block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::qpsk_demapper_vcb. - * - * To avoid accidental use of raw pointers, dab::qpsk_demapper_vcb's - * constructor is in a private implementation - * class. dab::qpsk_demapper_vcb::make is the public interface for - * creating new instances. - */ - static sptr make(int symbol_length); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_QPSK_DEMAPPER_VCB_H */ - diff --git a/include/dab/qpsk_mapper_vbc.h b/include/dab/qpsk_mapper_vbvc.h similarity index 73% rename from include/dab/qpsk_mapper_vbc.h rename to include/dab/qpsk_mapper_vbvc.h index 7ef0accd..3c6335c1 100644 --- a/include/dab/qpsk_mapper_vbc.h +++ b/include/dab/qpsk_mapper_vbvc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2015 <+YOU OR YOUR COMPANY+>. + * 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 @@ -19,8 +19,8 @@ */ -#ifndef INCLUDED_DAB_QPSK_MAPPER_VBC_H -#define INCLUDED_DAB_QPSK_MAPPER_VBC_H +#ifndef INCLUDED_DAB_QPSK_MAPPER_VBVC_H +#define INCLUDED_DAB_QPSK_MAPPER_VBVC_H #include #include @@ -33,24 +33,24 @@ namespace gr { * \ingroup dab * */ - class DAB_API qpsk_mapper_vbc : virtual public gr::sync_block + class DAB_API qpsk_mapper_vbvc : virtual public gr::sync_block { public: - typedef boost::shared_ptr sptr; + typedef boost::shared_ptr sptr; /*! - * \brief Return a shared_ptr to a new instance of dab::qpsk_mapper_vbc. + * \brief Return a shared_ptr to a new instance of dab::qpsk_mapper_vbvc. * - * To avoid accidental use of raw pointers, dab::qpsk_mapper_vbc's + * To avoid accidental use of raw pointers, dab::qpsk_mapper_vbvc's * constructor is in a private implementation - * class. dab::qpsk_mapper_vbc::make is the public interface for + * class. dab::qpsk_mapper_vbvc::make is the public interface for * creating new instances. */ - static sptr make(int symbol_length); + static sptr make(unsigned int symbol_length); }; } // namespace dab } // namespace gr -#endif /* INCLUDED_DAB_QPSK_MAPPER_VBC_H */ +#endif /* INCLUDED_DAB_QPSK_MAPPER_VBVC_H */ diff --git a/include/dab/repartition_vectors.h b/include/dab/repartition_vectors.h deleted file mode 100644 index d691b74e..00000000 --- a/include/dab/repartition_vectors.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2015 <+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_DAB_REPARTITION_VECTORS_H -#define INCLUDED_DAB_REPARTITION_VECTORS_H - -#include -#include - -namespace gr { - namespace dab { - - /*! - * \brief <+description of block+> - * \ingroup dab - * - */ - class DAB_API repartition_vectors : virtual public gr::block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::repartition_vectors. - * - * To avoid accidental use of raw pointers, dab::repartition_vectors's - * constructor is in a private implementation - * class. dab::repartition_vectors::make is the public interface for - * creating new instances. - */ - static sptr make(size_t itemsize, unsigned int vlen_in, unsigned int vlen_out, unsigned int multiply, unsigned int divide); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_REPARTITION_VECTORS_H */ - diff --git a/include/dab/select_vectors.h b/include/dab/select_cus_vfvf.h similarity index 52% rename from include/dab/select_vectors.h rename to include/dab/select_cus_vfvf.h index bf91e90b..21ec00c8 100644 --- a/include/dab/select_vectors.h +++ b/include/dab/select_cus_vfvf.h @@ -1,6 +1,11 @@ /* -*- c++ -*- */ /* - * Copyright 2015 <+YOU OR YOUR COMPANY+>. + * 2018 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * The content of this class is adopted from ODR-DabMod and written into a GNU Radio OutOfTree block. + * + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty + the Queen in Right of Canada (Communications Research Center Canada) + See https://github.com/Opendigitalradio/ODR-DabMod for licensing information of ODR-DabMod. * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +24,8 @@ */ -#ifndef INCLUDED_DAB_SELECT_VECTORS_H -#define INCLUDED_DAB_SELECT_VECTORS_H +#ifndef INCLUDED_DAB_SELECT_CUS_VFVF_H +#define INCLUDED_DAB_SELECT_CUS_VFVF_H #include #include @@ -29,28 +34,28 @@ namespace gr { namespace dab { /*! - * \brief <+description of block+> + * \brief selects a number of CUs (capacity units) of a vector * \ingroup dab * */ - class DAB_API select_vectors : virtual public gr::block + class DAB_API select_cus_vfvf : virtual public gr::block { public: - typedef boost::shared_ptr sptr; + typedef boost::shared_ptr sptr; /*! - * \brief Return a shared_ptr to a new instance of dab::select_vectors. + * \brief Return a shared_ptr to a new instance of dab::select_cus_vfvf. * - * To avoid accidental use of raw pointers, dab::select_vectors's + * To avoid accidental use of raw pointers, dab::select_cus_vfvf's * constructor is in a private implementation - * class. dab::select_vectors::make is the public interface for + * class. dab::select_cus_vfvf::make is the public interface for * creating new instances. */ - static sptr make(size_t itemsize, unsigned int length, unsigned int num_select, unsigned int num_skip); + static sptr make(unsigned int vlen, unsigned int frame_len, unsigned int address, unsigned int size); }; } // namespace dab } // namespace gr -#endif /* INCLUDED_DAB_SELECT_VECTORS_H */ +#endif /* INCLUDED_DAB_SELECT_CUS_VFVF_H */ diff --git a/include/dab/select_subch_vfvf.h b/include/dab/select_subch_vfvf.h deleted file mode 100644 index 949b5337..00000000 --- a/include/dab/select_subch_vfvf.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). - * - * 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_DAB_SELECT_SUBCH_VFVF_H -#define INCLUDED_DAB_SELECT_SUBCH_VFVF_H - -#include -#include - -namespace gr { - namespace dab { - -/*! \brief selects vectors out of input vectors that belong to one subchannel - * - * input: float vector of size vlen_in - * - * output: float vector of size vlen_out - * - * selects vlen_out/vlen_in vectors of total_size input vectors, beginning at address - * - * @param vlen_in Length of input vector in floats. - * @param vlen_out Length of output vector in floats. - * @param address number of input vector where output the output vector begins - * @param total_size size in input vectors of one frame (dumped after output vector is selected) - */ - class DAB_API select_subch_vfvf : virtual public gr::block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::select_subch_vfvf. - * - * To avoid accidental use of raw pointers, dab::select_subch_vfvf's - * constructor is in a private implementation - * class. dab::select_subch_vfvf::make is the public interface for - * creating new instances. - */ - static sptr make(unsigned int vlen_in, unsigned int vlen_out, unsigned int address, unsigned int total_size); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_SELECT_SUBCH_VFVF_H */ - diff --git a/include/dab/unpuncture_ff.h b/include/dab/unpuncture_ff.h deleted file mode 100644 index ca303577..00000000 --- a/include/dab/unpuncture_ff.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). - * - * 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_DAB_UNPUNCTURE_FF_H -#define INCLUDED_DAB_UNPUNCTURE_FF_H - -#include -#include - -namespace gr { - namespace dab { - - /*! - * unpuncturing of a stream sequence - * - */ - class DAB_API unpuncture_ff : virtual public gr::block - { - public: - typedef boost::shared_ptr sptr; - - /*! - * \brief Return a shared_ptr to a new instance of dab::unpuncture_ff. - * - * To avoid accidental use of raw pointers, dab::unpuncture_ff's - * constructor is in a private implementation - * class. dab::unpuncture_ff::make is the public interface for - * creating new instances. - */ - static sptr make(const std::vector &puncturing_vector, float fillval=0); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_UNPUNCTURE_FF_H */ - diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 3992c30e..f56adf13 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -25,27 +25,12 @@ include(GrPlatform) #define LIB_SUFFIX include_directories(${Boost_INCLUDE_DIR} ${FDK-AAC-DAB_INCLUDE_DIRS} ${LIBTOOLAME-DAB_INCLUDE_DIR}) link_directories(${Boost_LIBRARY_DIRS}) list(APPEND dab_sources - moving_sum_ff_impl.cc - ofdm_ffe_all_in_one_impl.cc - ofdm_sampler_impl.cc - ofdm_coarse_frequency_correct_impl.cc diff_phasor_vcc_impl.cc - ofdm_remove_first_symbol_vcc_impl.cc frequency_interleaver_vcc_impl.cc - qpsk_demapper_vcb_impl.cc complex_to_interleaved_float_vcf_impl.cc - modulo_ff_impl.cc - measure_processing_rate_impl.cc - select_vectors_impl.cc - repartition_vectors_impl.cc unpuncture_vff_impl.cc - prune_vectors_impl.cc fib_sink_vb_impl.cc crc16.cc - estimate_sample_rate_bf_impl.cc - fractional_interpolator_triggered_update_cc_impl.cc - magnitude_equalizer_vcc_impl.cc - qpsk_mapper_vbc_impl.cc ofdm_insert_pilot_vcc_impl.cc sum_phasor_trig_vcc_impl.cc ofdm_move_and_insert_zero_impl.cc @@ -54,15 +39,13 @@ list(APPEND dab_sources time_deinterleave_ff_impl.cc crc16_bb_impl.cc fib_source_b_impl.cc - select_subch_vfvf_impl.cc - unpuncture_ff_impl.cc + select_cus_vfvf_impl.cc prune_impl.cc firecode-checker.cpp firecode_check_bb_impl.cc puncture_bb_impl.cc dab_transmission_frame_mux_bb_impl.cc conv_encoder_bb_impl.cc - mapper_bc_impl.cc mp2_decode_bs_impl.cc mp4_decode_bs_impl.cc reed_solomon_decode_bb_impl.cc @@ -94,7 +77,10 @@ list(APPEND dab_sources ${LIBTOOLAME-DAB_SOURCE_DIR}/encode_new.c ${LIBTOOLAME-DAB_SOURCE_DIR}/portableio.c valve_ff_impl.cc - peak_detector_fb_impl.cc ) + ofdm_synchronization_cvf_impl.cc + ofdm_coarse_frequency_correction_vcvc_impl.cc + demux_cc_impl.cc + qpsk_mapper_vbvc_impl.cc ) set(dab_sources "${dab_sources}" PARENT_SCOPE) diff --git a/lib/Introduction.md b/lib/Introduction.md index c189374a..f99db8dc 100644 --- a/lib/Introduction.md +++ b/lib/Introduction.md @@ -3,4 +3,4 @@ The GNU Radio Out-Of-Tree module gr-dab contains the necessary signal processing Copyright (C) Andreas Müller, 2011 -Additions made by Moritz Luca Schmid, 2017 (Google Summer of Code Project 2017, details see https://dabtransceiver.wordpress.com/about/) +Copyright (C) Moritz Luca Schmid, 2017 (Google Summer of Code Project 2017, details see https://dabtransceiver.wordpress.com/about/) diff --git a/lib/complex_to_interleaved_float_vcf_impl.cc b/lib/complex_to_interleaved_float_vcf_impl.cc index f6180020..fcd409dc 100644 --- a/lib/complex_to_interleaved_float_vcf_impl.cc +++ b/lib/complex_to_interleaved_float_vcf_impl.cc @@ -35,41 +35,39 @@ namespace gr { namespace dab { -complex_to_interleaved_float_vcf::sptr -complex_to_interleaved_float_vcf::make(unsigned int length) -{ - return gnuradio::get_initial_sptr - (new complex_to_interleaved_float_vcf_impl(length)); -} + complex_to_interleaved_float_vcf::sptr + complex_to_interleaved_float_vcf::make(unsigned int length) { + return gnuradio::get_initial_sptr(new complex_to_interleaved_float_vcf_impl(length)); + } + + complex_to_interleaved_float_vcf_impl::complex_to_interleaved_float_vcf_impl(unsigned int length) + : gr::sync_block("complex_to_interleaved_float_vcf", + gr::io_signature::make(1, 1, + sizeof(gr_complex) * length), + gr::io_signature::make(1, 1, + sizeof(float) * length * 2)), + d_length(length) { + } -complex_to_interleaved_float_vcf_impl::complex_to_interleaved_float_vcf_impl(unsigned int length) - : gr::sync_block("complex_to_interleaved_float_vcf", - gr::io_signature::make (1, 1, sizeof(gr_complex)*length), - gr::io_signature::make (1, 1, sizeof(float)*length*2)), - d_length(length) -{ -} + int + complex_to_interleaved_float_vcf_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + gr_complex const *in = (const gr_complex *) input_items[0]; + float *out = (float *) output_items[0]; -int -complex_to_interleaved_float_vcf_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - gr_complex const *in = (const gr_complex *) input_items[0]; - float *out = (float *) output_items[0]; + for (int i = 0; i < noutput_items; i++) { + for (unsigned int j = 0; j < d_length; j++) { + out[j] = in[j].real(); + out[j + d_length] = in[j].imag(); + } + in += d_length; + out += 2 * d_length; + } - for (int i=0; i - +/*! \brief transforms a complex vector into a real vector + * The first half of the output vector includes the real parts of the + * complex input vector, followed by the imaginary parts. + * + * @param length length of the complex input vector + */ namespace gr { namespace dab { -class complex_to_interleaved_float_vcf_impl : public complex_to_interleaved_float_vcf -{ - private: + class complex_to_interleaved_float_vcf_impl : public complex_to_interleaved_float_vcf { + private: + unsigned int d_length; /*!< length of the complex input vector */ - unsigned int d_length; + public: + complex_to_interleaved_float_vcf_impl(unsigned int length); - public: - complex_to_interleaved_float_vcf_impl(unsigned int length); - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -} + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + } } #endif /* INCLUDED_DAB_COMPLEX_TO_INTERLEAVED_FLOAT_VCF_H */ diff --git a/lib/conv_encoder_bb_impl.cc b/lib/conv_encoder_bb_impl.cc index c00ee5f2..8b0ab495 100644 --- a/lib/conv_encoder_bb_impl.cc +++ b/lib/conv_encoder_bb_impl.cc @@ -35,8 +35,7 @@ namespace gr { namespace dab { conv_encoder_bb::sptr - conv_encoder_bb::make(int framesize) - { + conv_encoder_bb::make(int framesize) { return gnuradio::get_initial_sptr (new conv_encoder_bb_impl(framesize)); } @@ -66,9 +65,9 @@ namespace gr { conv_encoder_bb_impl::conv_encoder_bb_impl(int framesize) : gr::block("conv_encoder_bb", gr::io_signature::make(1, 1, sizeof(unsigned char)), - gr::io_signature::make(1, 1, sizeof(unsigned char))), - d_framesize(framesize) - { + gr::io_signature::make(1, 1, + sizeof(unsigned char))), + d_framesize(framesize) { d_outsize = (d_framesize * 4) + 3; set_output_multiple(framesize * 4 + 3); } @@ -76,13 +75,12 @@ namespace gr { /* * Our virtual destructor. */ - conv_encoder_bb_impl::~conv_encoder_bb_impl() - { + conv_encoder_bb_impl::~conv_encoder_bb_impl() { } void - conv_encoder_bb_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { + conv_encoder_bb_impl::forecast(int noutput_items, + gr_vector_int &ninput_items_required) { ninput_items_required[0] = (noutput_items / (d_framesize * 4 + 3)) * d_framesize; } @@ -90,8 +88,7 @@ namespace gr { conv_encoder_bb_impl::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { const unsigned char *in = (const unsigned char *) input_items[0]; unsigned char *out = (unsigned char *) output_items[0]; d_memory = 0; diff --git a/lib/conv_encoder_bb_impl.h b/lib/conv_encoder_bb_impl.h index 62317903..a43de27a 100644 --- a/lib/conv_encoder_bb_impl.h +++ b/lib/conv_encoder_bb_impl.h @@ -31,10 +31,12 @@ namespace gr { namespace dab { -/*! \brief convolutional encoding for DAB without puncturing +/*! \brief convolutional encoding for DAB/DAB+ without puncturing * * convolutional encoder according to DAB standard ETSI EN 300 401 V1.4.1 - * code rate R=1/4, polyonoms in octal form: [133, 171, 145, 133], appends 3*8 tailbits to mother codeword (flush out of state register) + * code rate R=1/4, polyonoms in octal form: [133, 171, 145, 133], + * appends 3*8 tailbits to mother codeword (flush out of state register) + * * input and output are packed bytes * * @param framesize size of packed bytes in one frame; output framelenght is 4*framesize+3 in packed bytes @@ -42,10 +44,10 @@ namespace gr { */ class conv_encoder_bb_impl : public conv_encoder_bb { private: - int d_framesize; - int d_outsize; - unsigned int d_in_offset, d_out_offset; - uint16_t d_memory; + int d_framesize; /*!< size of packed bytes in one frame */ + int d_outsize; /*!< = d_framesize * 4 + 3 */ + unsigned int d_in_offset, d_out_offset; /*!< control variable for buffer read/write operations */ + uint16_t d_memory; /*!< virtual shift register for convolutional encoder */ public: @@ -54,14 +56,14 @@ namespace gr { ~conv_encoder_bb_impl(); // Where all the action really happens - void forecast(int noutput_items, gr_vector_int &ninput_items_required); + void + forecast(int noutput_items, gr_vector_int &ninput_items_required); int general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); }; - } // namespace dab } // namespace gr diff --git a/lib/crc16_bb_impl.cc b/lib/crc16_bb_impl.cc index 95bbe040..b7d11e45 100644 --- a/lib/crc16_bb_impl.cc +++ b/lib/crc16_bb_impl.cc @@ -30,27 +30,27 @@ namespace gr { namespace dab { crc16_bb::sptr - crc16_bb::make(int length = 32, uint16_t generator = 0x1021, uint16_t initial_state = 0xFF) - { - return gnuradio::get_initial_sptr - (new crc16_bb_impl(length, generator, initial_state)); + crc16_bb::make(int length = 32, uint16_t generator = 0x1021, + uint16_t initial_state = 0xFF) { + return gnuradio::get_initial_sptr(new crc16_bb_impl(length, generator, initial_state)); } - crc16_bb_impl::crc16_bb_impl(int length, uint16_t generator, uint16_t initial_state) + crc16_bb_impl::crc16_bb_impl(int length, uint16_t generator, + uint16_t initial_state) : gr::block("crc16_bb", - gr::io_signature::make(1, 1, length * sizeof(char)), /*FIB without CRC (zeros instead)*/ - gr::io_signature::make(1, 1, length * sizeof(char))), /*FIB with CRC16*/ - d_length(length), d_generator(generator), d_initial_state(initial_state) - { + /*Input item: FIB without CRC, but zeros instead.*/ + gr::io_signature::make(1, 1, length * sizeof(char)), + /*Output item: FIB with CRC16.*/ + gr::io_signature::make(1, 1, length * sizeof(char))), + d_length(length), d_generator(generator), + d_initial_state(initial_state) { } - crc16_bb_impl::~crc16_bb_impl() - { + crc16_bb_impl::~crc16_bb_impl() { } void - crc16_bb_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { + crc16_bb_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) { ninput_items_required[0] = noutput_items; } @@ -58,8 +58,7 @@ namespace gr { crc16_bb_impl::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { const char *in = (const char *) input_items[0]; char *out = (char *) output_items[0]; @@ -76,10 +75,11 @@ namespace gr { GR_LOG_DEBUG(d_logger, "CRC16 overwrites data (zeros expected)"); } - //write calculated crc to vector (overwrite last 2 bytes) - out[d_length - 2 + n * d_length] = (char) (d_crc >> 8);//add MSByte first to FIB - out[d_length - 1 + n * d_length] = - (char) (out[d_length - 2 + n * d_length] << 8) ^ d_crc; //add LSByte second to FIB + // Write calculated crc to vector. (overwrite last 2 bytes) + // Add MSByte first to FIB. + out[d_length - 2 + n * d_length] = (char) (d_crc >> 8); + // Add LSByte second to FIB. + out[d_length - 1 + n * d_length] = (char) (out[d_length - 2 + n * d_length] << 8) ^ d_crc; } // Tell runtime system how many input items we consumed on // each input stream. diff --git a/lib/crc16_test.cc b/lib/crc16_test.cc deleted file mode 100644 index e3e63461..00000000 --- a/lib/crc16_test.cc +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include -#include "crc16.h" - -char packet[] = {0x05,0x00,0x10,0x08,0x0E,0x3C,0x17,0x01,0x2C,0x00,0x88,0x30,0x3C,0x30,0x23,0x40,0x90,0x23,0x44,0xF0,0x2D,0x49,0x7C,0x1A,0x4D,0xC2,0x10,0x51,0xF2,0x23,0x7B,0xFA}; - -int main(void) { - uint16_t actual; - printf("actual CRC: %x\n",(uint8_t)packet[30]*256+(uint8_t)packet[31]); - actual = (uint8_t)packet[30]*256+(uint8_t)packet[31]; - printf("CRC of whole packet (should be zero): %x\n",crc16(packet,32,0x1021,0xffff)); - assert(crc16(packet,32,0x1021,0xffff)==0); - packet[10]=0; - printf("CRC of whole packet withe error (should not be zero): %x\n",crc16(packet,32,0x1021,0xffff)); - assert(crc16(packet,32,0x1021,0xffff)!=0); - packet[10] = 0x88; - packet[30]=0; - packet[31]=0; - printf("calculated CRC: %x\n",crc16(packet,32,0x1021,0xffff)); - assert(actual==crc16(packet,32,0x1021,0xffff)); - printf("ALL TESTS OK\n"); -} diff --git a/lib/dab_concatenate_signals.cc b/lib/dab_concatenate_signals.cc deleted file mode 100644 index 38324428..00000000 --- a/lib/dab_concatenate_signals.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; 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 - -#include -#include - -#include -#include - -dab_concatenate_signals_sptr -dab_make_concatenate_signals (size_t itemsize) -{ - return gnuradio::get_initial_sptr (new dab_concatenate_signals (itemsize)); -} - -dab_concatenate_signals::dab_concatenate_signals (size_t itemsize) - : gr_block ("concatenate_signals", - gr_make_io_signature (1, -1, itemsize), - gr_make_io_signature (1, 1, itemsize)), - d_itemsize(itemsize), d_current_signal(0), d_callmetwice(1) -{ -} - -void -dab_concatenate_signals::forecast (int noutput_items, gr_vector_int &ninput_items_required) -{ - unsigned int ninputs = ninput_items_required.size(); - // printf("noutput_items: %d\n", noutput_items); - - if (d_current_signal make sure the scheduler notices it */ - for (unsigned i = 0; i < ninputs; i++) - ninput_items_required[i] = noutput_items; - } -} - - -int -dab_concatenate_signals::general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - unsigned int ninputs = input_items.size (); - int produced; - - // for (unsigned int i=0; i < ninputs; i++) - // printf("input %d: has %d items\n", i, ninput_items[i]); - // printf("current signal: %d\n", d_current_signal); - - if (d_current_signal == ninputs) /* no more streams - finished */ - return -1; - - if (ninput_items[d_current_signal]==0) { /* no more input - go to next stream */ - if (d_callmetwice == 0) /* workaround: general_work gets called with no inputs right at the start in any case */ - d_current_signal++; - else - d_callmetwice--; - // sched_yield(); [> let other threads run .. <] - return 0; - } - - d_callmetwice = 1; - - produced = (noutput_items - -class dab_concatenate_signals; -typedef boost::shared_ptr dab_concatenate_signals_sptr; - -dab_concatenate_signals_sptr dab_make_concatenate_signals (size_t itemsize); - -/*! - * \brief Concatenate all input signals in time - * - * \ingroup flow - * \param itemsize size of input and output items - * - * output: first input stream, as long as it has samples, then second input stream, etc... - * - * Note: Altough this block works with simple vectors, it seems that samples - * get lost when more complicated blocks are used. - */ -class dab_concatenate_signals : public gr_block -{ - private: - friend dab_concatenate_signals_sptr dab_make_concatenate_signals (size_t itemsize); - - dab_concatenate_signals (size_t itemsize); - - size_t d_itemsize; - unsigned int d_current_signal; - unsigned int d_callmetwice; - - public: - - void forecast (int noutput_items, gr_vector_int &ninput_items_required); - int general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - void reset() { d_current_signal=0; } -}; - -#endif diff --git a/lib/dab_correct_individual_phase_offset_vff.cc b/lib/dab_correct_individual_phase_offset_vff.cc deleted file mode 100644 index 74e527c8..00000000 --- a/lib/dab_correct_individual_phase_offset_vff.cc +++ /dev/null @@ -1,101 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#define M_PI_HALF M_PI/2 -#define M_PI_QUARTER M_PI/4 - -/* - * Create a new instance of dab_correct_individual_phase_offset_vff and return - * a boost shared_ptr. This is effectively the public constructor. - */ -dab_correct_individual_phase_offset_vff_sptr -dab_make_correct_individual_phase_offset_vff (unsigned int vlen, float alpha) -{ - return gnuradio::get_initial_sptr (new dab_correct_individual_phase_offset_vff (vlen, alpha)); -} - -dab_correct_individual_phase_offset_vff::dab_correct_individual_phase_offset_vff (unsigned int vlen, float alpha) : - gr_sync_block ("correct_individual_phase_offset_vff", - gr_make_io_signature (1, 1, sizeof(float)*vlen), - gr_make_io_signature (1, 1, sizeof(float)*vlen)), - d_vlen(vlen), d_alpha(alpha), d_debug(0) -{ - d_offset_estimation = new float[vlen]; - for (unsigned int i=0;iM_PI_HALF) // poor man's modulo pi/2 - ival-=M_PI_HALF; - while (ival<0) - ival+=M_PI_HALF; - d_offset_estimation[j] = (1-d_alpha)*d_offset_estimation[j] + d_alpha*(ival-M_PI_QUARTER); - out[0] = in[0] - d_offset_estimation[j]; - out++; - in++; - } - } - - /* debug */ - /* - d_debug++; - if (d_debug==10 || d_debug==50 || d_debug==100||d_debug==500) { - fprintf(stderr, "individual_phase_offset=["); - for (unsigned int i=0; i - -class dab_correct_individual_phase_offset_vff; - -/* - * We use boost::shared_ptr's instead of raw pointers for all access - * to gr_blocks (and many other data structures). The shared_ptr gets - * us transparent reference counting, which greatly simplifies storage - * management issues. This is especially helpful in our hybrid - * C++ / Python system. - * - * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm - * - * As a convention, the _sptr suffix indicates a boost::shared_ptr - */ -typedef boost::shared_ptr dab_correct_individual_phase_offset_vff_sptr; - -/*! - * \brief Return a shared_ptr to a new instance of dab_correct_individual_phase_offset_vff. - * - * To avoid accidental use of raw pointers, dab_correct_individual_phase_offset_vff's - * constructor is private. dab_make_correct_individual_phase_offset_vff is the public - * interface for creating new instances. - */ -dab_correct_individual_phase_offset_vff_sptr -dab_make_correct_individual_phase_offset_vff (unsigned int vlen, float alpha); - -/*! - * \brief Corrects the individual phase offset of each subcarrier by doing an estimation of the error. - * \ingroup DAB - * - * \param vlen length of the vector - * \param alpha adaptation speed fatcor: corr = (1-alpha)*corr + alpha*new_val) - * - * input: float vector stream with phase vectors of symbols - * output: float vector stream with corrected phases - * - * Note: This block only makes sense as long as the offset of the majority of - * the samples is smaller than pi/4 - */ -class dab_correct_individual_phase_offset_vff : public gr_sync_block -{ - private: - // The friend declaration allows dab_make_correct_individual_phase_offset_vff to - // access the private constructor. - - friend dab_correct_individual_phase_offset_vff_sptr - dab_make_correct_individual_phase_offset_vff (unsigned int vlen, float alpha); - - dab_correct_individual_phase_offset_vff (unsigned int vlen, float alpha); // private constructor - - unsigned int d_vlen; - float d_alpha; - float * d_offset_estimation; - unsigned int d_debug; - - public: - ~dab_correct_individual_phase_offset_vff (void); - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif /* INCLUDED_DAB_CORRECT_INDIVIDUAL_PHASE_OFFSET_VFF_H */ diff --git a/lib/dab_measure_ber_b.cc b/lib/dab_measure_ber_b.cc deleted file mode 100644 index a0c27113..00000000 --- a/lib/dab_measure_ber_b.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2006,2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; 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 - -#include -#include -#include - -dab_measure_ber_b_sptr -dab_make_measure_ber_b () -{ - return gnuradio::get_initial_sptr (new dab_measure_ber_b ()); -} - -dab_measure_ber_b::dab_measure_ber_b() - : gr_sync_block ("measure_ber_b", - gr_make_io_signature2(2, 2, sizeof(char), sizeof(char)), - gr_make_io_signature(0, 0, 0)), - d_bytes(0), d_errors(0) -{ -} - -unsigned int dab_measure_ber_b::bits_set(char byte) { - char bits = 0; - for (int i=0; i<8; i++) - if (byte&(1< - -class dab_measure_ber_b; -typedef boost::shared_ptr dab_measure_ber_b_sptr; - -dab_measure_ber_b_sptr dab_make_measure_ber_b(); - -/*! - * \brief Measure bit error rate of a byte stream - * - * input: port 0: actual byte stream - * input: port 1: expected byte stream - * - * \ingroup sink - */ -class dab_measure_ber_b : public gr_sync_block -{ - friend dab_measure_ber_b_sptr dab_make_measure_ber_b(); - - private: - unsigned long d_bytes; - unsigned long d_errors; - - protected: - unsigned int bits_set(char byte); - dab_measure_ber_b(); - - public: - /*! clear error and byte count */ - void clear() { d_errors=0; d_bytes=0; } - /*! \return bit error rate */ - float ber() { return (float)d_errors/(float)(d_bytes*8); } - /*! \return number of received bytes */ - unsigned long bytecount() { return d_bytes; } - /*! \return number of received bits */ - unsigned long bitcount() { return 8*d_bytes; } - /*! \return number of received bits with errors */ - unsigned long errorcount() { return d_errors; } - - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif /* INCLUDED_DAB_MEASURE_BER_B_H */ diff --git a/lib/dab_moving_sum_cc.cc b/lib/dab_moving_sum_cc.cc deleted file mode 100644 index 5f0d2e0a..00000000 --- a/lib/dab_moving_sum_cc.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -/* - * Create a new instance of dab_moving_sum_cc and return - * a boost shared_ptr. This is effectively the public constructor. - */ -dab_moving_sum_cc_sptr -dab_make_moving_sum_cc (int length) -{ - return gnuradio::get_initial_sptr (new dab_moving_sum_cc (length)); -} - -/* - * Specify constraints on number of input and output streams. - * This info is used to construct the input and output signatures - * (2nd & 3rd args to gr_block's constructor). The input and - * output signatures are used by the runtime system to - * check that a valid number and type of inputs and outputs - * are connected to this block. In this case, we accept - * only 1 input and 1 output. - */ -static const int MIN_IN = 1; // mininum number of input streams -static const int MAX_IN = 1; // maximum number of input streams -static const int MIN_OUT = 1; // minimum number of output streams -static const int MAX_OUT = 1; // maximum number of output streams - -/* - * The private constructor - */ -dab_moving_sum_cc::dab_moving_sum_cc (int length) - : gr_sync_block ("moving_sum_cc", - gr_make_io_signature (MIN_IN, MAX_IN, sizeof (gr_complex)), - gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (gr_complex))), - d_sum(0), d_length(length) -{ - assert(length>=0); - set_history(length+1); - set_output_multiple(length+1); -} - -/* - * Our virtual destructor. - */ -dab_moving_sum_cc::~dab_moving_sum_cc () -{ - // nothing else required in this example -} - -int -dab_moving_sum_cc::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *in = (const gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; - - for (int i=0; i < noutput_items; i++) { - d_sum+=(gr_complexd)in[i+d_length]-(gr_complexd)in[i]; - out[i] = (gr_complex)d_sum; - } - - // Tell runtime system how many output items we produced. - return noutput_items; -} diff --git a/lib/dab_moving_sum_cc.h b/lib/dab_moving_sum_cc.h deleted file mode 100644 index 97ab0117..00000000 --- a/lib/dab_moving_sum_cc.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ -#ifndef INCLUDED_DAB_MOVING_SUM_CC_H -#define INCLUDED_DAB_MOVING_SUM_CC_H - -#include - -class dab_moving_sum_cc; - -typedef boost::shared_ptr dab_moving_sum_cc_sptr; - -dab_moving_sum_cc_sptr dab_make_moving_sum_cc (int length); - -/*! - * \brief Moving sum over a stream of complex floats. - * \ingroup filter - * \param length length of the moving sum (=number of taps) - * - * input: complex - * output: complex - * - * This is the same as an FIR filter with length taps 1, but much faster - * (linear time instead of O(n*m)). On the other hand, since only the diff is - * calculated for each sample, there is some chance of an accumulating error. - */ -class dab_moving_sum_cc : public gr_sync_block -{ -private: - // The friend declaration allows dab_make_moving_sum_cc to - // access the private constructor. - - friend dab_moving_sum_cc_sptr dab_make_moving_sum_cc (int length); - - dab_moving_sum_cc (int length); // private constructor - - gr_complexd d_sum; - int d_length; - - public: - ~dab_moving_sum_cc (); // public destructor - int length() const {return d_length;} - void reset() {d_sum=0;} - - // Where all the action really happens - - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif /* INCLUDED_DAB_MOVING_SUM_CC_H */ diff --git a/lib/dab_ofdm_ffs_sample.cc b/lib/dab_ofdm_ffs_sample.cc deleted file mode 100644 index fba0754f..00000000 --- a/lib/dab_ofdm_ffs_sample.cc +++ /dev/null @@ -1,132 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include - -/* - * Create a new instance of dab_ofdm_ffs_sample and return - * a boost shared_ptr. This is effectively the public constructor. - */ -dab_ofdm_ffs_sample_sptr -dab_make_ofdm_ffs_sample (unsigned int symbol_length, unsigned int fft_length, unsigned int num_symbols, float alpha, unsigned int sample_rate) -{ - return gnuradio::get_initial_sptr (new dab_ofdm_ffs_sample (symbol_length, fft_length, num_symbols, alpha, sample_rate)); -} - -dab_ofdm_ffs_sample::dab_ofdm_ffs_sample (unsigned int symbol_length, unsigned int fft_length, unsigned int num_symbols, float alpha, unsigned int sample_rate) : - gr_sync_block ("ofdm_ffs_sample", - gr_make_io_signature2 (2, 2, sizeof(float), sizeof(char)), - gr_make_io_signature (1, 1, sizeof(float))), - d_symbol_length(symbol_length), d_fft_length(fft_length), d_num_symbols(num_symbols), d_alpha(alpha), d_sample_rate(sample_rate), d_cur_symbol(num_symbols), d_cur_sample(0), d_ffs_error_sum(0), d_estimated_error(0), d_estimated_error_per_sample(0) -{ -} - - - -int -dab_ofdm_ffs_sample::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const float *iptr = (const float *) input_items[0]; - const char *trigger = (const char *) input_items[1]; - float *optr = (float *) output_items[0]; - - float new_estimate; - - for (int i=0; i0) { - if (d_ffs_error_sum < 0 && new_estimate > 0 && new_estimate - d_ffs_error_sum/d_cur_symbol > M_PI) - new_estimate -= 2*M_PI; - else if (d_ffs_error_sum > 0 && new_estimate < 0 && d_ffs_error_sum/d_cur_symbol - new_estimate > M_PI) - new_estimate += 2*M_PI; - } - - d_ffs_error_sum += new_estimate; - } - - if (d_cur_symbol == d_num_symbols-1) { /* update estimated error */ - d_ffs_error_sum /= d_num_symbols; /* average */ - - /* if the offset is close to half of the subcarrier bandwidth, it may - * jump from some large positive value to some large negative value. - * with averaging, this is a problem - we have to detect it (although - * it really only makes a difference when the offset is very close to - * half the subcarrier bandwidth) - - * note: if there is an offset of one subcarrier bandwidth, the phase - * offset in fft_length samples is 2pi */ - if (d_estimated_error < 0 && d_ffs_error_sum > 0 && d_ffs_error_sum - d_estimated_error > M_PI) { - fprintf(stderr, "ofdm_ffs_sample: switch detected: neg -> pos\n"); - d_estimated_error += 2*M_PI; - } else if (d_estimated_error > 0 && d_ffs_error_sum < 0 && d_estimated_error - d_ffs_error_sum > M_PI) { - fprintf(stderr, "ofdm_ffs_sample: switch detected: pos -> neg\n"); - d_estimated_error -= 2*M_PI; - } - - /* the following distinction is not really needed; but without it, - * simulation would need to run much longer, becuase the - * synchronisation would need time to adjust to the offset */ - if (d_estimated_error == 0) - d_estimated_error = d_ffs_error_sum; /* first time -> fast adjustment */ - else - d_estimated_error = d_alpha*d_ffs_error_sum + (1-d_alpha)*d_estimated_error; /* slow adjustment */ - - d_estimated_error_per_sample = d_estimated_error / (float)d_fft_length; - // fprintf(stderr, "ofdm_ffs_sample: d_estimated_error: %f (%3.2f Hz)\n", d_estimated_error, d_estimated_error_per_sample*d_sample_rate/(2*M_PI)); - } - - d_cur_symbol++; - } - - *optr++ = d_estimated_error_per_sample; - iptr++; - } - - return noutput_items; -} diff --git a/lib/dab_ofdm_ffs_sample.h b/lib/dab_ofdm_ffs_sample.h deleted file mode 100644 index 575259f7..00000000 --- a/lib/dab_ofdm_ffs_sample.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ -#ifndef INCLUDED_DAB_OFDM_FFS_SAMPLE_H -#define INCLUDED_DAB_OFDM_FFS_SAMPLE_H - -#include - -class dab_ofdm_ffs_sample; - -typedef boost::shared_ptr dab_ofdm_ffs_sample_sptr; - -dab_ofdm_ffs_sample_sptr dab_make_ofdm_ffs_sample (unsigned int symbol_length, unsigned int fft_length, unsigned int num_symbols, float alpha, unsigned int sample_rate); - -/*! - * \brief samples FFS error estimation at the correct time and averages it - * \ingroup DAB - * \param symbol_length number of samples in an OFDM symbol - * \param fft_length number of samples in an OFDM symbol without the cyclic prefix - * \param num_symbols number of symbols to use for averaging (more symbols is better, but symbols towards the end of the frame tend to have larger time offsets and worse values) - * \param alpha how fast should we adapt to new FFS error values (1=immediately) - * \param sample_rate sampling rate - needed to calculate the offset estimation in Hz - * - * input: port 0: float - actual data; port 1: byte - trigger signal indicating the start of a frame - * output: float fine frequency offset estimation (in radian per sample) - */ -class dab_ofdm_ffs_sample : public gr_sync_block -{ - private: - // The friend declaration allows dab_make_ofdm_ffs_sample to - // access the private constructor. - - friend dab_ofdm_ffs_sample_sptr dab_make_ofdm_ffs_sample (unsigned int symbol_length, unsigned int fft_length, unsigned int num_symbols, float alpha, unsigned int sample_rate); - - dab_ofdm_ffs_sample (unsigned int symbol_length, unsigned int fft_length, unsigned int num_symbols, float alpha, unsigned int sample_rate); // private constructor - - unsigned int d_symbol_length; // length of a symbol in samples - unsigned int d_fft_length; // length of a symbol without cyclic prefix in samples - unsigned int d_num_symbols; // number of symbols per frame to average over - float d_alpha; // adjustment speed factor - unsigned int d_sample_rate; // sample rate -- only needed to print the ffs error in Hz - - unsigned int d_cur_symbol; // which symbol in the frame is currently under observation? - unsigned int d_cur_sample; // which sample in the symbol is currently under observation? - float d_ffs_error_sum; // sum of error samples in current frame - float d_estimated_error; // total estimated error - float d_estimated_error_per_sample; // total estimated error / fft_length - - public: - /*! \return fine frequency error estimate in Hz */ - float ffe_estimate() { return d_estimated_error_per_sample*d_sample_rate/(2*M_PI); } - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif /* INCLUDED_DAB_OFDM_FFS_SAMPLE_H */ diff --git a/lib/dab_puncture_vbb.cc b/lib/dab_puncture_vbb.cc deleted file mode 100644 index 59524f0b..00000000 --- a/lib/dab_puncture_vbb.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -/* - * Create a new instance of dab_puncture_vbb and return - * a boost shared_ptr. This is effectively the public constructor. - */ -dab_puncture_vbb_sptr -dab_make_puncture_vbb(const std::vector &puncturing_vector) -{ - return gnuradio::get_initial_sptr(new dab_puncture_vbb(puncturing_vector)); -} - -unsigned int dab_puncture_vbb::ones(const std::vector &puncturing_vector) -{ - unsigned int onescount = 0; - for (unsigned int i = 0; i < puncturing_vector.size(); i++) { - if (puncturing_vector[i] == 1) - onescount++; - } - return onescount; -} - -dab_puncture_vbb::dab_puncture_vbb(const std::vector &puncturing_vector) : - gr_sync_block("puncture_vbb", - gr_make_io_signature(1, 1, sizeof(char) * puncturing_vector.size()), - gr_make_io_signature(1, 1, sizeof(char) * ones(puncturing_vector))), - d_puncturing_vector(puncturing_vector) -{ - d_vlen_in = puncturing_vector.size(); - d_vlen_out = ones(puncturing_vector); -} - -int -dab_puncture_vbb::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - int i; - unsigned int j; - - const char *in = (const char *) input_items[0]; - char *out = (char *) output_items[0]; - - for (i = 0; i < noutput_items; i++) { - for (j = 0; j < d_vlen_in; j++) { - if (d_puncturing_vector[j] == 1) { - *out++ = *in++; - } else - in++; - } - } - - return noutput_items; -} diff --git a/lib/dab_puncture_vbb.h b/lib/dab_puncture_vbb.h deleted file mode 100644 index 9d4eafc2..00000000 --- a/lib/dab_puncture_vbb.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DAB_PUNCTURE_VBB_H -#define INCLUDED_DAB_PUNCTURE_VBB_H - -#include - -class dab_puncture_vbb; - -typedef boost::shared_ptr dab_puncture_vbb_sptr; - -dab_puncture_vbb_sptr -dab_make_puncture_vbb(const std::vector &puncturing_vector); - -/*! - * \brief Puncturing - remove bits, where the puncturing sequence is zero - * \ingroup DAB - * \param puncturing_vector describes, which bits are removed (1=keep, 0=remove) - * - * input: byte vector whose length equals the length of the puncturing vector - * output: byte vector whose length equeals the number of ones in the puncturing vector - */ -class dab_puncture_vbb : public gr_sync_block { -private: - friend dab_puncture_vbb_sptr - dab_make_puncture_vbb(const std::vector &puncturing_vector); - - unsigned int ones(const std::vector &puncturing_vector); - - dab_puncture_vbb(const std::vector &puncturing_vector); // private constructor - - std::vector d_puncturing_vector; - unsigned int d_vlen_in; - unsigned int d_vlen_out; - -public: - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif /* INCLUDED_DAB_PUNCTURE_VBB_H */ diff --git a/lib/dab_sum_elements_vff.cc b/lib/dab_sum_elements_vff.cc deleted file mode 100644 index 66d16355..00000000 --- a/lib/dab_sum_elements_vff.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include - -/* - * Create a new instance of dab_sum_elements_vff and return - * a boost shared_ptr. This is effectively the public constructor. - */ -dab_sum_elements_vff_sptr -dab_make_sum_elements_vff (unsigned int length) -{ - return gnuradio::get_initial_sptr (new dab_sum_elements_vff (length)); -} - -dab_sum_elements_vff::dab_sum_elements_vff (unsigned int length) : - gr_sync_block ("sum_elements_vff", - gr_make_io_signature (1, 1, sizeof(float)*length), - gr_make_io_signature (1, 1, sizeof(float))), - d_length(length) -{ -} - - -int -dab_sum_elements_vff::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const float *in = (const float *) input_items[0]; - float *out = (float *) output_items[0]; - - double sum; - - for (int i = 0; i < noutput_items; i++){ - sum = 0; - for (unsigned int j = 0; j < d_length; j++) - sum += *in++; - *out++ = (float)sum; - } - - return noutput_items; -} diff --git a/lib/dab_sum_elements_vff.h b/lib/dab_sum_elements_vff.h deleted file mode 100644 index 45d9fbaa..00000000 --- a/lib/dab_sum_elements_vff.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ -#ifndef INCLUDED_DAB_SUM_ELEMENTS_VFF_H -#define INCLUDED_DAB_SUM_ELEMENTS_VFF_H - -#include - -class dab_sum_elements_vff; - -/* - * We use boost::shared_ptr's instead of raw pointers for all access - * to gr_blocks (and many other data structures). The shared_ptr gets - * us transparent reference counting, which greatly simplifies storage - * management issues. This is especially helpful in our hybrid - * C++ / Python system. - * - * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm - * - * As a convention, the _sptr suffix indicates a boost::shared_ptr - */ -typedef boost::shared_ptr dab_sum_elements_vff_sptr; - -/*! - * \brief Return a shared_ptr to a new instance of dab_sum_elements_vff. - * - * To avoid accidental use of raw pointers, dab_sum_elements_vff's - * constructor is private. dab_make_sum_elements_vff is the public - * interface for creating new instances. - */ -dab_sum_elements_vff_sptr -dab_make_sum_elements_vff (unsigned int length); - -/*! - * \brief Sum up all elements of a vector - * \ingroup math - * \param length length of the vector - * \return \f[ y[k] = \sum_{i=1}^n x_i[k]\f] - * - * input: float vector - * output: float - */ -class dab_sum_elements_vff : public gr_sync_block -{ - private: - // The friend declaration allows dab_make_sum_elements_vff to - // access the private constructor. - - friend dab_sum_elements_vff_sptr - dab_make_sum_elements_vff (unsigned int length); - - dab_sum_elements_vff (unsigned int length); // private constructor - - unsigned int d_length; - - public: - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif /* INCLUDED_DAB_SUM_ELEMENTS_VFF_H */ diff --git a/lib/dab_transmission_frame_mux_bb_impl.cc b/lib/dab_transmission_frame_mux_bb_impl.cc index b33e3b54..49c849ee 100644 --- a/lib/dab_transmission_frame_mux_bb_impl.cc +++ b/lib/dab_transmission_frame_mux_bb_impl.cc @@ -31,22 +31,24 @@ namespace gr { dab_transmission_frame_mux_bb::sptr dab_transmission_frame_mux_bb::make(int transmission_mode, int num_subch, - const std::vector &subch_size) - { - return gnuradio::get_initial_sptr - (new dab_transmission_frame_mux_bb_impl(transmission_mode, num_subch, subch_size)); + const std::vector &subch_size) { + return gnuradio::get_initial_sptr( + new dab_transmission_frame_mux_bb_impl(transmission_mode, + num_subch, subch_size)); } /* * The private constructor */ - dab_transmission_frame_mux_bb_impl::dab_transmission_frame_mux_bb_impl(int transmission_mode, int num_subch, - const std::vector &subch_size) + dab_transmission_frame_mux_bb_impl::dab_transmission_frame_mux_bb_impl( + int transmission_mode, int num_subch, + const std::vector &subch_size) : gr::block("dab_transmission_frame_mux_bb", - gr::io_signature::make(1 + num_subch, 1 + num_subch, sizeof(unsigned char)), + gr::io_signature::make(1 + num_subch, 1 + num_subch, + sizeof(unsigned char)), gr::io_signature::make(1, 1, sizeof(unsigned char))), - d_transmission_mode(transmission_mode), d_subch_size(subch_size), d_num_subch(num_subch) - { + d_transmission_mode(transmission_mode), d_subch_size(subch_size), + d_num_subch(num_subch) { switch (transmission_mode) { case 1: d_num_fibs = 12; @@ -65,7 +67,8 @@ namespace gr { d_num_cifs = 2; break; default: - throw std::invalid_argument((boost::format("Transmission mode %d doesn't exist") % transmission_mode).str()); + throw std::invalid_argument((boost::format("Transmission mode %d doesn't exist") + % transmission_mode).str()); } if (subch_size.size() != num_subch) { GR_LOG_WARN(d_logger, "sizeof vector subch_size does not match with num_subch"); @@ -77,27 +80,26 @@ namespace gr { d_subch_total_size += subch_size[i]; } if (d_subch_total_size * d_cu_len > d_cif_len) { - throw std::out_of_range((boost::format("subchannels are %d bytes too long for CIF") % (d_subch_total_size * d_cu_len - d_cif_len)).str()); + throw std::out_of_range((boost::format("subchannels are %d bytes too long for CIF") + % (d_subch_total_size * d_cu_len - d_cif_len)).str()); } - GR_LOG_DEBUG(d_logger, boost::format("MUX init with: fic_len = %d, subch_total_size = %d, vlen_out = %d")%d_fic_len %d_subch_total_size %d_vlen_out); + GR_LOG_DEBUG(d_logger, boost::format( "MUX init with: fic_len = %d, subch_total_size = %d, vlen_out = %d") + % d_fic_len % d_subch_total_size % d_vlen_out); set_output_multiple(d_vlen_out); - // generate PRBS for padding generate_prbs(d_prbs, sizeof(d_prbs)); - GR_LOG_DEBUG(d_logger, boost::format("key num_subch: %d") %d_num_subch); + GR_LOG_DEBUG(d_logger, boost::format("key num_subch: %d") % d_num_subch); } /* * Our virtual destructor. */ - dab_transmission_frame_mux_bb_impl::~dab_transmission_frame_mux_bb_impl() - { + dab_transmission_frame_mux_bb_impl::~dab_transmission_frame_mux_bb_impl() { } void - dab_transmission_frame_mux_bb_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { + dab_transmission_frame_mux_bb_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) { // the first input is always the FIC ninput_items_required[0] = d_fic_len * (noutput_items / d_vlen_out); for (int i = 0; i < d_num_subch; ++i) { @@ -107,8 +109,7 @@ namespace gr { } void - dab_transmission_frame_mux_bb_impl::generate_prbs(unsigned char *out_ptr, int length) - { + dab_transmission_frame_mux_bb_impl::generate_prbs(unsigned char *out_ptr, int length) { char bits[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1}; char newbit; unsigned char temp = 0; @@ -129,18 +130,8 @@ namespace gr { dab_transmission_frame_mux_bb_impl::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { unsigned char *out = (unsigned char *) output_items[0]; - //unsigned char *triggerout = (unsigned char *) output_items[1]; - //const unsigned char *in; - - // create control stream for ofdm with trigger at start of frame and set zero - /*memset(triggerout, 0, noutput_items); - for (int i = 0; i < noutput_items / d_vlen_out; ++i) { - triggerout[i * d_vlen_out] = 1; - }*/ - // write FIBs const unsigned char *in_fic = (const unsigned char *) input_items[0]; for (int i = 0; i < noutput_items / d_vlen_out; ++i) { @@ -153,22 +144,21 @@ namespace gr { const unsigned char *in_msc = (const unsigned char *) input_items[j + 1]; for (int i = 0; i < noutput_items / d_vlen_out; ++i) { for (int k = 0; k < d_num_cifs; ++k) { - memcpy(out + i * d_vlen_out + d_fic_len + k * d_cif_len + cu_index * d_cu_len, in_msc + (i * d_num_cifs + k) * d_subch_size[j] * d_cu_len, d_subch_size[j] * d_cu_len); - //printf("input %d, item %d, cif %d, in_adress %d, in_val %d, out_adress %d\n", j, i, k, (i*d_num_cifs + k)*d_subch_size[j]*d_cu_len, in[(i*d_num_cifs + k)*d_subch_size[j]*d_cu_len], i*d_vlen_out + d_fic_len + k*d_cif_len + cu_index*d_cu_len); + memcpy(out + i * d_vlen_out + d_fic_len + k * d_cif_len + cu_index * d_cu_len, + in_msc + (i * d_num_cifs + k) * d_subch_size[j] * d_cu_len, + d_subch_size[j] * d_cu_len); } } cu_index += d_subch_size[j]; } // fill remaining cus with padding for (int i = 0; i < noutput_items / d_vlen_out; ++i) { - //memcpy(out + i*d_vlen_out + d_num_fibs*d_fib_len + d_subch_total_size*d_cu_len, d_prbs + d_subch_total_size*d_cu_len*8, (d_vlen_out - d_num_fibs*d_fib_len - d_subch_total_size*d_cu_len)*8); for (int j = d_subch_total_size * d_cu_len; j < d_cif_len; ++j) { for (int k = 0; k < d_num_cifs; ++k) { out[i * d_vlen_out + d_fic_len + k * d_cif_len + j] = d_prbs[j]; } } } - // Tell runtime system how many input items we consumed on // each input stream. consume(0, noutput_items / d_vlen_out * d_fic_len); diff --git a/lib/dab_transmission_frame_mux_bb_impl.h b/lib/dab_transmission_frame_mux_bb_impl.h index 40ff73f9..c646afd6 100644 --- a/lib/dab_transmission_frame_mux_bb_impl.h +++ b/lib/dab_transmission_frame_mux_bb_impl.h @@ -27,27 +27,40 @@ namespace gr { namespace dab { /*! \brief multiplex to DAB transmission frames * - * block multiplexes the FIBs of the FIC and all subchannels of the MCI to a transmission frame according to ETSI EN 300 401 - * the number of FIBs per CIF and the number of CIFs per transmission frame depends on the transmission mode - * the maximum number of supported sub-channels is 7 + * block multiplexes the FIBs of the FIC and all subchannels of the MCI to a + * transmission frame according to ETSI EN 300 401 + * the number of FIBs per CIF and the number of CIFs per transmission frame + * depends on the transmission mode * - * @param transmission_mode transmission mode 1-4 after DAB standard - * @param subch_size vector with size of each subchannel + * @param transmission_mode Transmission mode 1-4 after DAB standard. + * @param subch_size Vector with size of each sub-channel. */ - class dab_transmission_frame_mux_bb_impl : public dab_transmission_frame_mux_bb { + class dab_transmission_frame_mux_bb_impl + : public dab_transmission_frame_mux_bb { private: int d_transmission_mode; + /*!< Transmission_mode transmission mode 1-4 after DAB standard. */ int d_num_subch; + /*!< Number of sub-channels in the transmission frame and ensemble. */ std::vector d_subch_size; - const static unsigned int d_fib_len = 32*3; // length of a fib in bytes (*3 because bit rate = 1/3) - const static unsigned int d_cif_len = 6912; // length of a cif in bytes - const static unsigned int d_cu_len = 8; // length of a capacity unit in bytes + /*!< Vector containing the sizes in CUs of each subchannel. */ + const static unsigned int d_fib_len = 32 * 3; + /*!< Length of a fib in bytes. (*3 because bit rate = 1/3) */ + const static unsigned int d_cif_len = 6912; + /*!< Length of a Common Interleaved Frame (CIF) in bytes. */ + const static unsigned int d_cu_len = 8; + /*!< Length of a capacity unit in bytes. */ unsigned int d_vlen_out, d_num_cifs, d_num_fibs, d_subch_total_size; unsigned int d_fic_len; unsigned char d_prbs[d_cif_len]; + /*!< Vector for the PRBS, used for padding at the end of each frame. */ void generate_prbs(unsigned char *out_ptr, int length); + /*!< Generates a PRBS after the rules of ETSI EN 300 401 and writes it to output buffer out_ptr. + * @param length Required length of the PRBS and number of bytes that are written to out_ptr. + * @param out_ptr Pointer to the first element of the buffer to write the PRBS. + */ public: dab_transmission_frame_mux_bb_impl(int transmission_mode, int num_subch, diff --git a/lib/demux_cc_impl.cc b/lib/demux_cc_impl.cc new file mode 100644 index 00000000..fe01e5da --- /dev/null +++ b/lib/demux_cc_impl.cc @@ -0,0 +1,145 @@ +/* -*- c++ -*- */ +/* + * Copyright 2017, 2018 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * + * 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 + +#include +#include "demux_cc_impl.h" +#include +#include +#include + +using namespace boost; + +namespace gr { + namespace dab { + + demux_cc::sptr + demux_cc::make(unsigned int symbol_length, unsigned int symbols_fic, + unsigned int symbol_msc, gr_complex fillval) { + return gnuradio::get_initial_sptr(new demux_cc_impl(symbol_length, symbols_fic, + symbol_msc, fillval)); + } + + /* + * The private constructor + */ + demux_cc_impl::demux_cc_impl(unsigned int symbol_length, + unsigned int symbols_fic, + unsigned int symbol_msc, gr_complex fillval) + : gr::block("demux_cc", + gr::io_signature::make(1, 1, sizeof(gr_complex) * symbol_length), + gr::io_signature::make(2, 2, sizeof(gr_complex) * symbol_length)), + d_symbol_lenght(symbol_length), + d_symbols_fic(symbols_fic), + d_symbols_msc(symbol_msc), + d_fillval(fillval) { + set_tag_propagation_policy(TPP_DONT); + d_fic_counter = 0; + d_msc_counter = 0; + } + + /* + * Our virtual destructor. + */ + demux_cc_impl::~demux_cc_impl() { + } + + void + demux_cc_impl::forecast(int noutput_items, + gr_vector_int &ninput_items_required) { + ninput_items_required[0] = noutput_items; + } + + int + demux_cc_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + const gr_complex *in = (const gr_complex *) input_items[0]; + gr_complex *fic_out = (gr_complex *) output_items[0]; + gr_complex *msc_out = (gr_complex *) output_items[1]; + unsigned int nconsumed = 0; + unsigned int fic_syms_written = 0; + unsigned int msc_syms_written = 0; + + // get tags for the beginning of a frame + std::vector tags; + const std::string s = "Start"; + pmt::pmt_t d_key = pmt::string_to_symbol(s); + unsigned int tag_count = 0; + get_tags_in_window(tags, 0, 0, noutput_items, d_key); + + for (int i = 0; i < noutput_items; ++i) { + if (tag_count < tags.size() && + tags[tag_count].offset - nitems_read(0) - nconsumed == 0) { + // This input symbol is tagged: a new frame begins here. + if (d_fic_counter % d_symbols_fic == 0 && + d_msc_counter % d_symbols_msc == 0) { + /* We are at the beginning of a frame and also finished writing the last frame. + * We can remove this first symbol of the frame (phase reference symbol) + * and copy the other symbols. */ + tag_count++; + nconsumed++; + d_fic_counter = 0; + d_msc_counter = 0; + } else { + /* We did not finish the last frame, maybe we lost track in sync during a frame. + * Let's fill the remaining symbols with fillval + * before continuing with the new input frame. */ + if (d_fic_counter % d_symbols_fic != 0) { + memset(&fic_out[fic_syms_written++ * d_symbol_lenght], 0, + d_symbol_lenght * sizeof(gr_complex)); + d_fic_counter++; + } else { + memset(&msc_out[msc_syms_written++ * d_symbol_lenght], 0, + d_symbol_lenght * sizeof(gr_complex)); + d_msc_counter++; + } + } + } else if (d_fic_counter < d_symbols_fic) { + // copy this symbol to fic output. + memcpy(&fic_out[fic_syms_written++ * d_symbol_lenght], + &in[nconsumed++ * d_symbol_lenght], + d_symbol_lenght * sizeof(gr_complex)); + d_fic_counter++; + } else if (d_msc_counter < d_symbols_msc) { + // copy this output to msc output + memcpy(&msc_out[msc_syms_written++ * d_symbol_lenght], + &in[nconsumed++ * d_symbol_lenght], + d_symbol_lenght * sizeof(gr_complex)); + d_msc_counter++; + } + } + // Tell runtime system how many input items we consumed on + // each input stream. + consume_each(nconsumed); + + // Tell runtime system how many output items we produced on each output stream separately. + produce(0, fic_syms_written); + produce(1, msc_syms_written); + return WORK_CALLED_PRODUCE; + } + + } /* namespace dab */ +} /* namespace gr */ + diff --git a/lib/demux_cc_impl.h b/lib/demux_cc_impl.h new file mode 100644 index 00000000..387c4550 --- /dev/null +++ b/lib/demux_cc_impl.h @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2017, 2018 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * + * 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_DAB_DEMUX_CC_IMPL_H +#define INCLUDED_DAB_DEMUX_CC_IMPL_H + +#include + +namespace gr { + namespace dab { + /*! \brief Separation of FIC and MSC symbols. + * \param symbol_length number of samples per symbol + * \param symbols_fic number of symbols in the fic per transmission frame + * \param symobls_mic number of symbols in the msc per transmission frame + * \param fillval complex value to fill in if sync has been lost during frame + */ + + class demux_cc_impl : public demux_cc { + private: + unsigned int d_symbol_lenght; + /*!< Length in bytes of one OFDM symbol. */ + unsigned int d_symbols_fic; + /*!< Number of OFDM symbols with FIC content per transmission frame. */ + unsigned int d_symbols_msc; + /*!< Number of OFDM symbols with MSC content per transmission frame. */ + gr_complex d_fillval; + /*!< Complex value, used to fill gaps in the transmission frame + * (e.g. caused to a loss of sync) to avoid discontinuity in data flow. */ + + unsigned int d_fic_counter; + /*!< Counts the symbols containing fic data. + * The number of fic symbols per transmission frame does not match + * with the number of transmitted fibs. */ + unsigned int d_msc_counter; /*!< Counts the symbols containing msc data. */ + + public: + demux_cc_impl(unsigned int symbol_length, unsigned int symbols_fic, + unsigned int symbol_msc, gr_complex fillval); + + ~demux_cc_impl(); + + // Where all the action really happens + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace dab +} // namespace gr + +#endif /* INCLUDED_DAB_DEMUX_CC_IMPL_H */ + diff --git a/lib/diff_phasor_vcc_impl.cc b/lib/diff_phasor_vcc_impl.cc index 3ba6b616..cc904bd9 100644 --- a/lib/diff_phasor_vcc_impl.cc +++ b/lib/diff_phasor_vcc_impl.cc @@ -1,19 +1,19 @@ /* -*- c++ -*- */ /* * Copyright 2004 Free Software Foundation, Inc. - * + * * This file is part of GNU Radio - * + * * GNU Radio 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. - * + * * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, @@ -32,41 +32,35 @@ #include #include #include "diff_phasor_vcc_impl.h" +#include "volk/volk.h" namespace gr { namespace dab { -diff_phasor_vcc::sptr -diff_phasor_vcc::make(unsigned int length) -{ - return gnuradio::get_initial_sptr - (new diff_phasor_vcc_impl(length)); -} + diff_phasor_vcc::sptr + diff_phasor_vcc::make(unsigned int length) { + return gnuradio::get_initial_sptr + (new diff_phasor_vcc_impl(length)); + } -diff_phasor_vcc_impl::diff_phasor_vcc_impl(unsigned int length) - : gr::sync_block("diff_phasor_vcc", - gr::io_signature::make (1, 1, sizeof(gr_complex)*length), - gr::io_signature::make (1, 1, sizeof(gr_complex)*length)), - d_length(length) -{ - set_history(2); -} + diff_phasor_vcc_impl::diff_phasor_vcc_impl(unsigned int length) + : gr::sync_block("diff_phasor_vcc", + gr::io_signature::make(1, 1, sizeof(gr_complex) * length), + gr::io_signature::make(1, 1, sizeof(gr_complex) * length)), + d_length(length) { + set_history(2); + } -int -diff_phasor_vcc_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - gr_complex const *in = (const gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; + int + diff_phasor_vcc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + gr_complex const *in = (const gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + volk_32fc_x2_multiply_conjugate_32fc(out, in + d_length, in, noutput_items * d_length); + return noutput_items; + } - for(unsigned int i = 0; i < noutput_items*d_length; i++){ - out[i] = in[i+d_length] * conj(in[i]); } - - return noutput_items; -} - -} } diff --git a/lib/diff_phasor_vcc_impl.h b/lib/diff_phasor_vcc_impl.h index c5ae6f0f..2f9fdacb 100644 --- a/lib/diff_phasor_vcc_impl.h +++ b/lib/diff_phasor_vcc_impl.h @@ -26,21 +26,23 @@ namespace gr { namespace dab { +/*! \brief vector wise working differential phasor calculation + * this block has the same functionality as the gr-digital diff_phasor_cc block, + * but is working on vector basis. + */ + class diff_phasor_vcc_impl : public diff_phasor_vcc { + private: + unsigned int d_length; /*!< Length of each complex vector. */ -class diff_phasor_vcc_impl : public diff_phasor_vcc -{ - private: - - unsigned int d_length; + public: + diff_phasor_vcc_impl(unsigned int length); - public: - diff_phasor_vcc_impl(unsigned int length); - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; -} + } } #endif /* INCLUDED_DAB_DIFF_PHASOR_VCC_H */ diff --git a/lib/doxygen-config b/lib/doxygen-config index ecdb5808..87b11cad 100644 --- a/lib/doxygen-config +++ b/lib/doxygen-config @@ -441,7 +441,7 @@ EXTRACT_ALL = NO # be included in the documentation. # The default value is: NO. -EXTRACT_PRIVATE = NO +EXTRACT_PRIVATE = YES # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. diff --git a/lib/estimate_sample_rate_bf_impl.cc b/lib/estimate_sample_rate_bf_impl.cc deleted file mode 100644 index 478b8d26..00000000 --- a/lib/estimate_sample_rate_bf_impl.cc +++ /dev/null @@ -1,112 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include "estimate_sample_rate_bf_impl.h" - -namespace gr { - namespace dab { - -estimate_sample_rate_bf::sptr -estimate_sample_rate_bf::make(float expected_sample_rate, int frame_length) -{ - return gnuradio::get_initial_sptr - (new estimate_sample_rate_bf_impl(expected_sample_rate, frame_length)); -} - -/* - * Specify constraints on number of input and output streams. - * This info is used to construct the input and output signatures - * (2nd & 3rd args to gr_block's constructor). The input and - * output signatures are used by the runtime system to - * check that a valid number and type of inputs and outputs - * are connected to this block. In this case, we accept - * only 1 input and 1 output. - */ -static const int MIN_IN = 1; // mininum number of input streams -static const int MAX_IN = 1; // maximum number of input streams -static const int MIN_OUT = 1; // minimum number of output streams -static const int MAX_OUT = 1; // maximum number of output streams - -estimate_sample_rate_bf_impl::estimate_sample_rate_bf_impl(float expected_sample_rate, int frame_length) - : gr::sync_block("estimate_sample_rate_bf", - gr::io_signature::make (MIN_IN, MAX_IN, sizeof (char)), - gr::io_signature::make (MIN_OUT, MAX_OUT, sizeof (float))), - d_zeros(0), d_expected_sample_rate(expected_sample_rate), d_real_sample_rate(expected_sample_rate), d_found_first_frame(0), d_frame_length(frame_length) -{ -} - -/* - * Our virtual destructor. - */ -estimate_sample_rate_bf_impl::~estimate_sample_rate_bf_impl() -{ - // nothing else required in this example -} - -int -estimate_sample_rate_bf_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const char *in = (const char *) input_items[0]; - float *out = (float *) output_items[0]; - - int i=0; - if (d_found_first_frame) { - for(i=0; i - -namespace gr { - namespace dab { - -class estimate_sample_rate_bf_impl : public estimate_sample_rate_bf -{ - private: - - int d_zeros; - float d_expected_sample_rate; - float d_real_sample_rate; - char d_found_first_frame; - int d_frame_length; - - public: - estimate_sample_rate_bf_impl(float expected_sample_rate, int frame_length); - ~estimate_sample_rate_bf_impl (); // public destructor - - // Where all the action really happens - - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; -} -} -#endif /* INCLUDED_DAB_ESTIMATE_SAMPLE_RATE_BF_H */ - diff --git a/lib/fib_sink_vb_impl.cc b/lib/fib_sink_vb_impl.cc index 4ef9cc16..5eef6f83 100644 --- a/lib/fib_sink_vb_impl.cc +++ b/lib/fib_sink_vb_impl.cc @@ -1,8 +1,8 @@ /* -*- c++ -*- */ /* - * Copyright belongs to Andreas Mueller - * Modified 2017 by Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). - * + * Copyright 2017 by Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * Copyright 2008 by Andreas Mueller + * * 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) @@ -41,18 +41,14 @@ namespace gr { namespace dab { fib_sink_vb::sptr - fib_sink_vb::make() - { - return gnuradio::get_initial_sptr - (new fib_sink_vb_impl()); + fib_sink_vb::make() { + return gnuradio::get_initial_sptr(new fib_sink_vb_impl()); } - fib_sink_vb_impl::fib_sink_vb_impl() : gr::sync_block("fib_sink_vb", gr::io_signature::make(1, 1, sizeof(char) * 32), - gr::io_signature::make(0, 0, 0)) - { + gr::io_signature::make(0, 0, 0)) { d_service_info_written_trigger = -1; d_service_labels_written_trigger = -1; d_subch_info_written_trigger = -1; @@ -61,8 +57,7 @@ namespace gr { } int - fib_sink_vb_impl::process_fib(const char *fib) - { + fib_sink_vb_impl::process_fib(const char *fib) { uint8_t type, length, pos; if (crc16(fib, FIB_LENGTH, FIB_CRC_POLY, FIB_CRC_INITSTATE) != 0) { GR_LOG_DEBUG(d_logger, "FIB CRC error"); @@ -72,30 +67,38 @@ namespace gr { GR_LOG_DEBUG(d_logger, "FIB correct"); d_crc_passed = true; pos = 0; - while (pos < FIB_LENGTH - FIB_CRC_LENGTH && (uint8_t) fib[pos] != FIB_ENDMARKER && + while (pos < FIB_LENGTH - FIB_CRC_LENGTH && + (uint8_t) fib[pos] != FIB_ENDMARKER && (uint8_t) fib[pos] != 0) { //TODO correct? type = fib[pos] >> 5; length = fib[pos] & 0x1f; - assert(pos + length <= FIB_LENGTH - FIB_CRC_LENGTH); - assert(length != 0); + // if ((pos + length) > (FIB_LENGTH - FIB_CRC_LENGTH)){ + // GR_LOG_INFO(d_logger, "pos + length: " + std::to_string((pos + length))); + // return 1; + // } + // if (length != 0){ + // GR_LOG_INFO(d_logger, "length must be greater than zero!"); + // return 1; + // } process_fig(type, &fib[pos], length); pos += length + 1; } return 0; } - int - fib_sink_vb_impl::process_fig(uint8_t type, const char *data, uint8_t length) - { + void + fib_sink_vb_impl::process_fig(uint8_t type, const char *data, uint8_t length) { uint8_t cn, oe, pd, extension; switch (type) { case FIB_FIG_TYPE_MCI: GR_LOG_DEBUG(d_logger, "FIG type 0"); extension = (uint8_t)(data[1] & 0x1f); cn = (uint8_t)(data[1] & 0x80); - if (cn == 1) GR_LOG_DEBUG(d_logger, "[WARNING, INFO FOR FUTURE CONFIGURATION]: "); + if (cn == 1) + GR_LOG_DEBUG(d_logger, "[WARNING, INFO FOR FUTURE CONFIGURATION]: "); oe = (uint8_t)(data[1] & 0x40); - if (cn == 1) GR_LOG_DEBUG(d_logger, "[WARNING, INFO FOR OTHER ENSEMBLE]"); + if (cn == 1) + GR_LOG_DEBUG(d_logger, "[WARNING, INFO FOR OTHER ENSEMBLE]"); pd = (uint8_t)(data[1] & 0x20); if (pd == 1) GR_LOG_DEBUG(d_logger, "[WARNING, LONG IDENTIFIER"); @@ -107,14 +110,19 @@ namespace gr { uint8_t occurrence_change = data[6]; if (change_flag != 0) GR_LOG_DEBUG(d_logger, - format(", [CHANGE OF SUBCHANNEL OR SERVICE ORGA (%d)](at CIF %d) ") % (int) change_flag % + format(", [CHANGE OF SUBCHANNEL OR SERVICE ORGA (%d)](at CIF %d) ") % + (int) change_flag % (int) occurrence_change); uint8_t alarm_flag = (uint8_t)((data[4] & 0x20) >> 5); - if (alarm_flag == 1) GR_LOG_DEBUG(d_logger, ", [ALARM MESSAGE ACCESSIBLE] "); - uint16_t CIF_counter = (uint16_t)((data[4] & 0x1f) * 250 + (data[5])); + if (alarm_flag == 1) { + GR_LOG_DEBUG(d_logger, ", [ALARM MESSAGE ACCESSIBLE] "); + } + uint16_t CIF_counter = (uint16_t)( (data[4] & 0x1f) * 250 + (data[5])); GR_LOG_DEBUG(d_logger, - format("ensemble info: reference %d, country ID %d, CIF counter = %d") % ensemble_reference % - (int) country_ID % CIF_counter); + format("ensemble info: reference %d, country ID %d, CIF counter = %d") % + ensemble_reference % + (int) country_ID % + CIF_counter); break; } case FIB_MCI_EXTENSION_SUBCHANNEL_ORGA: { @@ -122,24 +130,30 @@ namespace gr { GR_LOG_DEBUG(d_logger, "subchannel orga: "); do { uint8_t subchID = (uint8_t)((data[2 + subch_counter] & 0xfc) >> 2); - uint16_t start_address = (uint16_t)((data[2 + subch_counter] & 0x03) << 8) | - (uint8_t)(data[3 + subch_counter]); + uint16_t start_address = (uint16_t)((data[2 + subch_counter] & 0x03) << 8) | (uint8_t)(data[3 + subch_counter]); uint8_t sl_form = (uint8_t)(data[4] & 0x80); if (sl_form == 0) { uint8_t table_switch = (uint8_t)(data[4 + subch_counter] & 0x40); - if (table_switch != 0) GR_LOG_DEBUG(d_logger, " [WARNING: OTHER TABLE USED] "); + if (table_switch != 0) { + GR_LOG_DEBUG(d_logger, " [WARNING: OTHER TABLE USED] "); + } uint8_t table_index = (uint8_t)(data[4 + subch_counter] & 0x3f); - GR_LOG_DEBUG(d_logger, format("subchID = %d , start address = %d, index %d") % (int) subchID % - (int) start_address % (int) table_index); + GR_LOG_DEBUG(d_logger, + format("subchID = %d , start address = %d, index %d") % + (int) subchID % + (int) start_address % + (int) table_index); subch_counter += 3; } else { uint8_t option = (uint8_t)(data[4 + subch_counter] & 0x70); uint8_t protect_level = (uint8_t)((data[4 + subch_counter] & 0x0c) >> 2); - uint16_t subch_size = (uint16_t)((data[4 + subch_counter] & 0x03) << 8) | - (uint8_t)(data[5 + subch_counter]); + uint16_t subch_size = (uint16_t)((data[4 + subch_counter] & 0x03) << 8) | (uint8_t)(data[5 + subch_counter]); GR_LOG_DEBUG(d_logger, format("subchID = %d , start address = %d, option %d, protect level %d, subch size %d") % - (int) subchID % (int) start_address % (int) option % (int) protect_level % + (int) subchID % + (int) start_address % + (int) option % + (int) protect_level % (int) subch_size); subch_counter += 4; @@ -148,8 +162,10 @@ namespace gr { d_subch_info_written_trigger = (int) subchID; } else { std::stringstream ss; - ss << d_subch_info_current << ",{" << "\"ID\":" << (int) subchID << ",\"address\":" - << (int) start_address << ",\"protection\":" << (int) protect_level << ",\"size\":" + ss << d_subch_info_current << ",{" << "\"ID\":" + << (int) subchID << ",\"address\":" + << (int) start_address << ",\"protection\":" + << (int) protect_level << ",\"size\":" << (int) subch_size << "}\0"; d_subch_info_current = ss.str(); if ((int) subchID == d_subch_info_written_trigger) { @@ -168,32 +184,39 @@ namespace gr { case FIB_MCI_EXTENSION_SERVICE_ORGA: { uint8_t service_counter = 1; do { //iterate over services - uint16_t service_reference = (uint16_t)(data[service_counter + 1] & 0x0f) << 8 | - (uint8_t) data[service_counter + 2]; + uint16_t service_reference = (uint16_t)(data[service_counter + 1] & 0x0f) << 8 | (uint8_t) data[service_counter + 2]; GR_LOG_DEBUG(d_logger, format("service orga: reference %d ") % service_reference); uint8_t local_flag = (uint8_t)((data[service_counter + 3] & 0x80) >> 7); - if (local_flag == 1) GR_LOG_DEBUG(d_logger, "[LOCAL FLAG SET] "); + if (local_flag == 1) { + GR_LOG_DEBUG(d_logger, "[LOCAL FLAG SET] "); + } uint8_t ca = (uint8_t)((data[service_counter + 3] & 0x70) >> 4); - if (ca != 0) GR_LOG_DEBUG(d_logger, "[CONDITIONAL ACCESS USED] "); + if (ca != 0) { + GR_LOG_DEBUG(d_logger, "[CONDITIONAL ACCESS USED] "); + } uint8_t num_service_comps = (uint8_t)(data[service_counter + 3] & 0x0f); GR_LOG_DEBUG(d_logger, format("(%d components):") % (int) num_service_comps); for (int i = 0; i < num_service_comps; i++) { //iterate over service components - uint8_t TMID = (uint8_t)((data[service_counter + 4 + i * 2] & 0xc0) >> 6); - uint8_t comp_type = (uint8_t)(data[service_counter + 4 + i * 2] & 0x3f); + uint8_t TMID = (uint8_t)( (data[service_counter + 4 + i * 2] & 0xc0) >> 6); + uint8_t comp_type = (uint8_t)( data[service_counter + 4 + i * 2] & 0x3f); uint8_t subchID = (uint8_t)((data[service_counter + 5 + i * 2] & 0xfc) >> 2); uint8_t ps = (uint8_t)((data[service_counter + 5 + i * 2 + 1] & 0x02) >> 1); if (TMID == 0) { GR_LOG_DEBUG(d_logger, - format("(audio stream, type %d, subchID %d, primary %d)") % (int) comp_type % + format("(audio stream, type %d, subchID %d, primary %d)") % + (int) comp_type % (int) subchID % (int) ps); // write service info from specififc subchannel to json if (d_service_info_written_trigger < 0) { d_service_info_written_trigger = (int) subchID; } else { std::stringstream ss; - ss << d_service_info_current << ",{" << "\"reference\":" << (int) service_reference << ",\"ID\":" - << (int) subchID << ",\"primary\":" << ((ps == 1) ? "true" : "false") << ",\"DAB+\":" - << (((int) comp_type == 63) ? "true" : "false") << "}\0"; + ss << d_service_info_current << ",{" << "\"reference\":" + << (int) service_reference << ",\"ID\":" + << (int) subchID << ",\"primary\":" + << ((ps == 1) ? "true" : "false") << ",\"DAB+\":" + << (((int) comp_type == 63) ? "true" : "false") + << "}\0"; d_service_info_current = ss.str(); if ((int) subchID == d_service_info_written_trigger) { std::stringstream ss_json; @@ -206,11 +229,15 @@ namespace gr { } } else if (TMID == 1) { GR_LOG_DEBUG(d_logger, - format("(data stream, type %d, subchID %d, primary %d)") % (int) comp_type % - (int) subchID % (int) ps); + format("(data stream, type %d, subchID %d, primary %d)") % + (int) comp_type % + (int) subchID % + (int) ps); } else if (TMID == 2) { GR_LOG_DEBUG(d_logger, - format("(FIDC, type %d, subchID %d, primary %d)") % (int) comp_type % (int) subchID % + format("(FIDC, type %d, subchID %d, primary %d)") % + (int) comp_type % + (int) subchID % (int) ps); } else { GR_LOG_DEBUG(d_logger, "[packed data]"); @@ -232,21 +259,25 @@ namespace gr { case FIB_MCI_EXTENSION_SERVICE_COMP_GLOBAL_DEFINITION: { uint8_t service_comp_counter = 0; do { - uint16_t service_reference = (uint16_t)(data[service_comp_counter + 2] & 0x0f) << 8 | - (uint8_t) data[service_comp_counter + 3]; + uint16_t service_reference = + (uint16_t)(data[service_comp_counter + 2] & 0x0f) << 8 | (uint8_t) data[service_comp_counter + 3]; uint8_t SCIdS = (uint8_t)(data[service_comp_counter + 4] & 0x0f); if ((data[service_comp_counter + 5] & 0x80) == 0) { uint8_t subchID = (uint8_t)(data[service_comp_counter + 5] & 0x3f); GR_LOG_DEBUG(d_logger, format("service component global definition: reference %d, SCIdS %d, subchID %d") % - service_reference % (int) SCIdS % (int) subchID); + service_reference % + (int) SCIdS % + (int) subchID); service_comp_counter += 5; } else { - uint16_t subchID = (uint16_t)(data[service_comp_counter + 5] & 0x0f) << 8 | - (uint8_t) data[service_comp_counter + 6]; + uint16_t subchID = + (uint16_t)(data[service_comp_counter + 5] & 0x0f)<< 8 | (uint8_t) data[service_comp_counter + 6]; GR_LOG_DEBUG(d_logger, format("service component global definition: reference %d, SCIdS %d, subchID %d") % - service_reference % (int) SCIdS % (int) subchID); + service_reference % + (int) SCIdS % + (int) subchID); service_comp_counter += 6; } } while (1 + service_comp_counter < length); @@ -265,19 +296,22 @@ namespace gr { GR_LOG_DEBUG(d_logger, "programme number"); break; case FIB_SI_EXTENSION_PROGRAMME_TYPE: { - GR_LOG_DEBUG(d_logger, format("programme type, %d components") %((length-1)/4)); - for(int i = 0; i < (length-1)/4; i++) { - uint8_t programme_type = (uint8_t)(data[2 + i*4 + 3] & 0x1f); - uint16_t service_reference = (uint16_t)(data[2 + i*4] & 0x0f) << 8 | - (uint8_t) data[2 + i*4 + 1]; - GR_LOG_DEBUG(d_logger, format("reference %d, type: %d") %service_reference %(int)programme_type); + GR_LOG_DEBUG(d_logger, format("programme type, %d components") % ((length - 1) / 4)); + for (int i = 0; i < (length - 1) / 4; i++) { + uint8_t programme_type = (uint8_t)(data[2 + i * 4 + 3] & 0x1f); + uint16_t service_reference = (uint16_t)(data[2 + i * 4] & 0x0f) << 8 | (uint8_t) data[2 + i * 4 + 1]; + GR_LOG_DEBUG(d_logger, + format("reference %d, type: %d") % + service_reference % + (int) programme_type); // write programme type to json if (d_programme_type_written_trigger < 0) { d_programme_type_written_trigger = (int) service_reference; } else { std::stringstream ss; - ss << d_programme_type_current << ",{" << "\"reference\":" << (int) service_reference << ",\"programme_type\":" + ss << d_programme_type_current << ",{" << "\"reference\":" + << (int) service_reference << ",\"programme_type\":" << (int) programme_type << "}\0"; d_programme_type_current = ss.str(); if ((int) service_reference == d_programme_type_written_trigger) { @@ -324,13 +358,15 @@ namespace gr { uint16_t service_reference = (uint16_t)(data[2] & 0x0f) << 8 | (uint8_t) data[3]; memcpy(label, &data[4], 16); GR_LOG_DEBUG(d_logger, - format("[programme service label] (reference %d): %s") % service_reference % label); + format("[programme service label] (reference %d): %s") % + service_reference % label); // write service labels from services to json if (d_service_labels_written_trigger < 0) { d_service_labels_written_trigger = (int) service_reference; } else { std::stringstream ss; - ss << d_service_labels_current << ",{" << "\"label\":\"" << label << "\",\"reference\":" + ss << d_service_labels_current << ",{" << "\"label\":\"" + << label << "\",\"reference\":" << (int) service_reference << "}\0"; d_service_labels_current = ss.str(); if ((int) service_reference == d_service_labels_written_trigger) { @@ -382,14 +418,12 @@ namespace gr { GR_LOG_DEBUG(d_logger, "unsupported FIG type"); break; } - return 0; } int fib_sink_vb_impl::work(int noutput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { const char *in = (const char *) input_items[0]; for (int i = 0; i < noutput_items; i++) { diff --git a/lib/fib_sink_vb_impl.h b/lib/fib_sink_vb_impl.h index da621a78..53a87682 100644 --- a/lib/fib_sink_vb_impl.h +++ b/lib/fib_sink_vb_impl.h @@ -1,7 +1,7 @@ /* -*- c++ -*- */ /* - * Copyright belongs to Andreas Mueller - * Modified 2017 by Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * Copyright 2017 by Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * Copyright 2008 by Andreas Mueller * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,15 +25,30 @@ namespace gr { namespace dab { -/*! \brief sink for DAB FIBs, interprets MSC and SI - * +/*! \brief sink for DAB/DAB+ FIBs, interprets MSC and SI + * CRC16 check of incoming fibs. + * Reads correct fibs. + * Generates json objects with service and multiplex information. */ class fib_sink_vb_impl : public fib_sink_vb { private: + /*! \brief Processes an incoming FIB. + * If CRC16 fails, dump the FIB, + * otherwise extract Fast Information Groups (FIGs) and read header information. + * + * @param fib Pointer to the first byte of the 30 byte FIB. + * @return 0 if CRC failed, 1 if CRC succeeded. + */ int process_fib(const char *fib); - - int process_fig(uint8_t type, const char *data, uint8_t length); + /*! \brief Processes a FIG. + * Switch between FIG types, extract information and write it to logger. + * Write and collect information in JSON objects for transport to GUI. + * @param type Type of the FIG. See ETSI EN 300 401 chapter 5.2.2. + * @param data Pointer to the FIG data buffer. + * @param length Length of the FIG data buffer in bytes. + */ + void process_fig(uint8_t type, const char *data, uint8_t length); bool d_crc_passed; @@ -55,28 +70,20 @@ namespace gr { std::string d_programme_type_current; int d_programme_type_written_trigger; - - public: fib_sink_vb_impl(); - virtual std::string get_ensemble_info() - { return d_json_ensemble_info; } + virtual std::string get_ensemble_info() { return d_json_ensemble_info; } - virtual std::string get_service_info() - { return d_json_service_info;} + virtual std::string get_service_info() { return d_json_service_info; } - virtual std::string get_service_labels() - { return d_json_service_labels;} + virtual std::string get_service_labels() { return d_json_service_labels; } - virtual std::string get_subch_info() - { return d_json_subch_info;} + virtual std::string get_subch_info() { return d_json_subch_info; } - virtual std::string get_programme_type() - { return d_json_programme_type;} + virtual std::string get_programme_type() { return d_json_programme_type; } - virtual bool get_crc_passed() - { return d_crc_passed;} + virtual bool get_crc_passed() { return d_crc_passed; } int work(int noutput_items, gr_vector_const_void_star &input_items, diff --git a/lib/fib_source_b_impl.cc b/lib/fib_source_b_impl.cc index d94278e3..ef59ae5b 100644 --- a/lib/fib_source_b_impl.cc +++ b/lib/fib_source_b_impl.cc @@ -31,340 +31,378 @@ #include namespace gr { - namespace dab { + namespace dab { //////////////////////////////////////// /// MCI-FIGs, ready to transmit //////////////////////////////////////// - //ensemble info, CIF counter has to increase with each CIF - const char fib_source_b_impl::d_ensemble_info[56] = {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - // 000 00110 000 00000 0100000000000000 00 0 0000000000000 00000000 + //ensemble info, CIF counter has to increase with each CIF + const char fib_source_b_impl::d_ensemble_info[56] = {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; + // 000 00110 000 00000 0100000000000000 00 0 0000000000000 00000000 - //service orga header - const char fib_source_b_impl::d_service_orga_header[16] = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}; - //000 00100 000 00010 + //service orga header + const char fib_source_b_impl::d_service_orga_header[16] = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}; + //000 00100 000 00010 - //service orga for one service containing one subchannel - const char fib_source_b_impl::d_service_orga[40] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}; - // 0100000000000000 0 000 0001 00 111111 000000 00 + //service orga for one service containing one subchannel + const char fib_source_b_impl::d_service_orga[40] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0}; + // 0100000000000000 0 000 0001 00 111111 000000 00 - //subchannel orga header, length has to be changed according to the number of subchannel-orga fields - const char fib_source_b_impl::d_subchannel_orga_header[16] = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; - //000 00100 000 00001 + //subchannel orga header, length has to be changed according to the number of subchannel-orga fields + const char fib_source_b_impl::d_subchannel_orga_header[16] = {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + //000 00100 000 00001 - //subchannel orga field (long form) (array has to be modified (subchID, start adress, protection level and subchannel size)) - const char fib_source_b_impl::d_subchannel_orga_field[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - // 000000 0000000000 0 1 000 00 0000000000 long form (table 7, p. 51) + //subchannel orga field (long form) (array has to be modified (subchID, start adress, protection level and subchannel size)) + const char fib_source_b_impl::d_subchannel_orga_field[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + // 000000 0000000000 0 1 000 00 0000000000 long form (table 7, p. 51) ///////////////////////////////////////////// /// SI-FIGs, ready to transmit ///////////////////////////////////////////// - //Ensemble label - char fib_source_b_impl::d_ensemble_label[176] = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, - 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, - 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, - 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, - 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, - 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, - 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, - 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, - 0}; - //"001 10101 0000 0 000 0000 000000000000 01011111 01011111 01000111 01100001 01101100 01100001 01111000 01111001 01011111 01001110 01100101 01110111 01110011 01011111 01011111 01011111 0011100011111000"; // Ensemble label: "__Galaxy_News___" + //Ensemble label + char fib_source_b_impl::d_ensemble_label[176] = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, + 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, + 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, + 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, + 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, + 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, + 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, + 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0}; + //"001 10101 0000 0 000 0000 000000000000 01011111 01011111 01000111 01100001 01101100 01100001 01111000 01111001 01011111 01001110 01100101 01110111 01110011 01011111 01011111 01011111 0011100011111000"; // Ensemble label: "__Galaxy_News___" - //Programme Service label - char fib_source_b_impl::d_programme_service_label[176] = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, - 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, - 1, 0, 0, - 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, - 0, 0, 1, - 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, - 0, 0, 1, - 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, - 0, 0, 0, - 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, - 1, 1, 0, - 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, - 1, 0, 1, - 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, - 1, 0, 0}; - //001 10101 0000 0 001 0100000000000000 01011111 01000111 01100001 01101100 01100001 01111000 01111001 01011111 01010010 01100001 01100100 01101001 01101111 00110001 01011111 01011111 0111000111100100 + //Programme Service label + char fib_source_b_impl::d_programme_service_label[176] = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, + 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, + 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, + 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, + 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, + 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, + 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0}; + //001 10101 0000 0 001 0100000000000000 01011111 01000111 01100001 01101100 01100001 01111000 01111001 01011111 01010010 01100001 01100100 01101001 01101111 00110001 01011111 01011111 0111000111100100 - fib_source_b::sptr - fib_source_b::make(int transmission_mode, int country_ID, int num_subch, std::string ensemble_label, - std::string programme_service_labels, std::string service_comp_label, uint8_t service_comp_lang, - const std::vector &protection_mode, const std::vector &data_rate_n, const std::vector &dabplus) - { - return gnuradio::get_initial_sptr - (new fib_source_b_impl(transmission_mode, country_ID, num_subch, ensemble_label, - programme_service_labels, service_comp_label, service_comp_lang, protection_mode, - data_rate_n, dabplus)); - } + fib_source_b::sptr + fib_source_b::make(int transmission_mode, int country_ID, int num_subch, + std::string ensemble_label, + std::string programme_service_labels, + std::string service_comp_label, + uint8_t service_comp_lang, + const std::vector &protection_mode, + const std::vector &data_rate_n, + const std::vector &dabplus) { + return gnuradio::get_initial_sptr(new fib_source_b_impl(transmission_mode, + country_ID, num_subch, + ensemble_label, + programme_service_labels, + service_comp_label, + service_comp_lang, + protection_mode, data_rate_n, + dabplus)); + } - /* - * The private constructor - */ - fib_source_b_impl::fib_source_b_impl(int transmission_mode, int country_ID, int num_subch, std::string ensemble_label, - std::string programme_service_labels, std::string service_comp_label, - uint8_t service_comp_lang, const std::vector &protection_mode, - const std::vector &data_rate_n, const std::vector &dabplus) - : gr::sync_block("fib_source_b", - gr::io_signature::make(0, 0, 0), - gr::io_signature::make(1, 1, sizeof(char))), - d_transmission_mode(transmission_mode), d_num_subch(num_subch), d_nFIBs_written(0), - d_protection_mode(protection_mode), d_data_rate_n(data_rate_n), d_dabplus(dabplus), d_country_ID(country_ID) - { - if (d_transmission_mode != 3) set_output_multiple((8 * FIB_LENGTH) * 3); - else set_output_multiple((8 * FIB_LENGTH) * 4); - //write the ensemble label with input string once at beginning - write_label(d_ensemble_label + 32, ensemble_label); - if (protection_mode.size() != num_subch) { - throw std::invalid_argument((boost::format("size of vector protection_mode (%d) does not fit with number of subchannels (%d)") % protection_mode.size() % num_subch).str()); - } - if (data_rate_n.size() != num_subch) { - throw std::invalid_argument((boost::format("size of vector data_rate_n (%d) does not fit with number of subchannels (%d)") % data_rate_n.size() % num_subch).str()); - } - // init counter for iterating over the services - d_label_counter = 0; - d_service_labels = programme_service_labels; - // the string programme_service_labels containts num_subch * 16 chars, appended. Note that every subchannel is strutured in a different service in this implementation. - if (programme_service_labels.size() != 16*num_subch){ - throw std::invalid_argument((boost::format("size of service label strings is (%d) but should be %d * 16 = %d") % programme_service_labels.size() % num_subch % (16*num_subch)).str()); - } - } + /* + * The private constructor + */ + fib_source_b_impl::fib_source_b_impl(int transmission_mode, + int country_ID, int num_subch, + std::string ensemble_label, + std::string programme_service_labels, + std::string service_comp_label, + uint8_t service_comp_lang, + const std::vector &protection_mode, + const std::vector &data_rate_n, + const std::vector &dabplus) + : gr::sync_block("fib_source_b", + gr::io_signature::make(0, 0, 0), + gr::io_signature::make(1, 1, sizeof(char))), + d_transmission_mode(transmission_mode), + d_num_subch(num_subch), d_nFIBs_written(0), + d_protection_mode(protection_mode), + d_data_rate_n(data_rate_n), d_dabplus(dabplus), + d_country_ID(country_ID) { + if (d_transmission_mode != 3) { + set_output_multiple((8 * FIB_LENGTH) * 3); + } else { + set_output_multiple((8 * FIB_LENGTH) * 4); + } + //write the ensemble label with input string once at beginning + write_label(d_ensemble_label + 32, ensemble_label); + if (protection_mode.size() != num_subch) { + throw std::invalid_argument((boost::format("size of vector protection_mode (%d) does not fit with number of subchannels (%d)") % + protection_mode.size() % + num_subch).str()); + } + if (data_rate_n.size() != num_subch) { + throw std::invalid_argument((boost::format("size of vector data_rate_n (%d) does not fit with number of subchannels (%d)") % + data_rate_n.size() % + num_subch).str()); + } + // init counter for iterating over the services + d_label_counter = 0; + d_service_labels = programme_service_labels; + /* The string programme_service_labels contains num_subch * 16 chars. + * Note that every subchannel is strutured in a different service in + * this implementation. */ + if (programme_service_labels.size() != 16 * num_subch) { + throw std::invalid_argument((boost::format("size of service label strings is (%d) but should be %d * 16 = %d") % + programme_service_labels.size() % + num_subch % (16 * num_subch)).str()); + } + } - /* - * Our virtual destructor. - */ - fib_source_b_impl::~fib_source_b_impl() - { - } + /* + * Our virtual destructor. + */ + fib_source_b_impl::~fib_source_b_impl() { + } - /* - * overwrites an integer value to num_bits bits to the num_bits bits before trigger (overwrites default zeros)), e.g. for number of subchannels in ensemble info - */ - void fib_source_b_impl::bit_adaption(char *out_ptr, int number, int num_bits) - { - for (int i = 0; i < num_bits; i++) { - if (pow(2, num_bits - 1 - i) > number) { - out_ptr[i - num_bits] = 0; - } else { - out_ptr[i - num_bits] = 1; - number -= pow(2, num_bits - 1 - i); + /* + * Overwrites an integer value to num_bits bits to the num_bits bits + * before trigger (overwrites default zeros)), + * e.g. for number of subchannels in ensemble info. + */ + void fib_source_b_impl::bit_adaption(char *out_ptr, int number, + int num_bits) { + for (int i = 0; i < num_bits; i++) { + if (pow(2, num_bits - 1 - i) > number) { + out_ptr[i - num_bits] = 0; + } else { + out_ptr[i - num_bits] = 1; + number -= pow(2, num_bits - 1 - i); + } + } } - } - } - /* - * calculates the CIF modulo counters and changes the bits in d_ensemble_info with bit_adaption - */ - void fib_source_b_impl::CIF_counter(char *out_ptr, int counter) - { - //mod 250 counter - int mod_250 = counter % 250; - bit_adaption(out_ptr, mod_250, 8); - //mod 20 counter - int mod_20 = ((counter - mod_250) / 250) % 20; - bit_adaption(out_ptr - 8, mod_20, 5); - } + /* + * Calculates the CIF modulo counters and changes the bits in + * d_ensemble_info with bit_adaption. + */ + void fib_source_b_impl::CIF_counter(char *out_ptr, int counter) { + // mod 250 counter + int mod_250 = counter % 250; + bit_adaption(out_ptr, mod_250, 8); + // mod 20 counter + int mod_20 = ((counter - mod_250) / 250) % 20; + bit_adaption(out_ptr - 8, mod_20, 5); + } - /* - * converts string to bits and writes it to the stream - * outputs the number of written bits to update d_offset - */ - int fib_source_b_impl::write_label(char *out_ptr, std::string label, int num_chars) - { - for (std::size_t i = 0; i < label.size(); ++i) { - bit_adaption(out_ptr + (i + 1) * 8, (int) label.c_str()[i], 8); - } - std::size_t written_size = label.size(); - while (written_size < num_chars) {//fill rest of label with spaces - bit_adaption(out_ptr + (written_size + 1) * 8, (int) ' ', 8); - written_size++; - } - return 8 * num_chars; - } + /* + * Converts string to bits and writes it to stream. + * Outputs the number of written bits to update d_offset. + */ + int fib_source_b_impl::write_label(char *out_ptr, std::string label, + int num_chars) { + for (std::size_t i = 0; i < label.size(); ++i) { + bit_adaption(out_ptr + (i + 1) * 8, (int) label.c_str()[i], 8); + } + std::size_t written_size = label.size(); + while (written_size < num_chars) {//fill rest of label with spaces + bit_adaption(out_ptr + (written_size + 1) * 8, (int) ' ', 8); + written_size++; + } + return 8 * num_chars; + } - int - fib_source_b_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { - char *out = (char *) output_items[0]; - d_offset = 0; + int + fib_source_b_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + char *out = (char *) output_items[0]; + d_offset = 0; - do { - //only MCI in this FIB when this FIB ist first in Row (Row are 3 FIBs for d_transmission_mode=1,2,4 or 4 FIBs for d_transmission_mode=3) - if ((d_nFIBs_written % 3 == 0 && d_transmission_mode != 3) || - (d_nFIBs_written % 4 == 0 && d_transmission_mode == 3)) { + do { + // Only MCI in this FIB when this FIB ist first in row. + // (Row are 3 FIBs for d_transmission_mode = 1,2,4 or + // 4 FIBs for d_transmission_mode = 3). + if ((d_nFIBs_written % 3 == 0 && d_transmission_mode != 3) || + (d_nFIBs_written % 4 == 0 && d_transmission_mode == 3)) { //////////////////////////////////////////////// /// add first FIB with only MCI (max services = 4) //////////////////////////////////////////////// - //ensemble info - std::memcpy(out + d_offset, d_ensemble_info, d_size_ensemble_info); - d_offset += d_size_ensemble_info; - //increase CIF counter - if (d_transmission_mode != 3) CIF_counter(out + d_offset, d_nFIBs_written / 3); - else CIF_counter(out + d_offset, d_nFIBs_written / 4); - - //service orga - //header - std::memcpy(out + d_offset, d_service_orga_header, d_size_service_orga_header); - d_offset += d_size_service_orga_header; - //change FIG length depending on number of services - bit_adaption(out + d_offset - 8, 1 + 5*d_num_subch, 5); - //data field for every service (each containing one service component) - for (int service_count = 0; service_count < d_num_subch; service_count++) { - std::memcpy(out + d_offset, d_service_orga, d_size_service_orga); - d_offset += d_size_service_orga; - //change service Identifier - bit_adaption(out + d_offset - 24, service_count, 8); - //change subchannel ID - bit_adaption(out + d_offset - 2, service_count, 6); - //change DAB+ mode if not DAB+ but DAB - if(d_dabplus[service_count] != 1){ - bit_adaption(out + d_offset -8, 0, 6); - } - } - //MCI is set, set EndMarker and padding - if ((8 * FIB_DATA_FIELD_LENGTH) - d_offset >= - 8) {//add EndMarker (111 11111) if there is minimum one byte left in FIG (FIG without 16 bit crc16) - for (int i = 0; i < 8; i++) { - out[i + d_offset] = 1; - } - } - d_offset += 8; - while (d_offset % (8 * FIB_LENGTH) != - 0) {//padding (fill rest of FIB with zeroes, as well the last 16 crc bits) - out[d_offset] = 0; - d_offset++; - } - d_nFIBs_written++; - }//first FIB in row (with only MCI) is finished + //ensemble info + std::memcpy(out + d_offset, d_ensemble_info, d_size_ensemble_info); + d_offset += d_size_ensemble_info; + // Increase CIF counter. + if (d_transmission_mode != 3) { + CIF_counter(out + d_offset, d_nFIBs_written / 3); + } else { + CIF_counter(out + d_offset, d_nFIBs_written / 4); + } + // service orga + // header + std::memcpy(out + d_offset, d_service_orga_header, d_size_service_orga_header); + d_offset += d_size_service_orga_header; + // Change FIG length depending on number of services. + bit_adaption(out + d_offset - 8, 1 + 5 * d_num_subch, 5); + // data field for every service (each containing one service component) + for (int service_count = 0; service_count < d_num_subch; service_count++) { + std::memcpy(out + d_offset, d_service_orga, d_size_service_orga); + d_offset += d_size_service_orga; + // change service Identifier + bit_adaption(out + d_offset - 24, service_count, 8); + // change subchannel ID + bit_adaption(out + d_offset - 2, service_count, 6); + // change DAB+ mode if not DAB+ but DAB + if (d_dabplus[service_count] != 1) { + bit_adaption(out + d_offset - 8, 0, 6); + } + } + // MCI is set, set EndMarker and padding. + if ((8 * FIB_DATA_FIELD_LENGTH) - d_offset >= 8) { + /* Add EndMarker (111 11111) if there is minimum one byte left + * in FIG (FIG without 16 bit crc16). */ + for (int i = 0; i < 8; i++) { + out[i + d_offset] = 1; + } + } + d_offset += 8; + /* Padding. (fill rest of FIB with zeroes, + * as well the last 16 crc bits) */ + while (d_offset % (8 * FIB_LENGTH) != 0) { + out[d_offset] = 0; + d_offset++; + } + d_nFIBs_written++; + } // First FIB in row (with only MCI) is finished. - //second FIB in row reserved for subchannel orga - else if ((d_nFIBs_written % 3 == 1 && d_transmission_mode != 3) || - (d_nFIBs_written % 4 == 1 && d_transmission_mode == 3)) { - //////////////////////////////////////////////// - /// add second FIB with only subchannel orga (max numSubCh = 7) - //////////////////////////////////////////////// - //subchannel orga - d_start_adress = 0; - //subchannel orga header (write only once for all subchannels) - std::memcpy(out + d_offset, d_subchannel_orga_header, d_size_subchannel_orga_header); - d_offset += d_size_subchannel_orga_header; - //change length of FIG header according to number of subchannel orga fields that are added - bit_adaption(out + d_offset - 8, d_num_subch * (d_size_subchannel_orga_field / 8) + 1, 5); - //subchannel orga field - for (int subch_count = 0; subch_count < d_num_subch; subch_count++) {//iterate over all subchannels - std::memcpy(out + d_offset + d_size_subchannel_orga_field * subch_count, d_subchannel_orga_field, - d_size_subchannel_orga_field); - d_offset += d_size_subchannel_orga_field; + // Second FIB in row reserved for subchannel orga. + else if ((d_nFIBs_written % 3 == 1 && d_transmission_mode != 3) || + (d_nFIBs_written % 4 == 1 && d_transmission_mode == 3)) { + //////////////////////////////////////////////// + /// add second FIB with only subchannel orga (max numSubCh = 7) + //////////////////////////////////////////////// + // subchannel orga + d_start_adress = 0; + // subchannel orga header (write only once for all subchannels) + std::memcpy(out + d_offset, d_subchannel_orga_header, d_size_subchannel_orga_header); + d_offset += d_size_subchannel_orga_header; + /* Change length of FIG header according to number of + * subchannel orga fields which are added. */ + bit_adaption(out + d_offset - 8, d_num_subch * (d_size_subchannel_orga_field / 8) + 1, 5); + // subchannel orga field + // Iterate over all subchannels. + for (int subch_count = 0; subch_count < d_num_subch; subch_count++) { + std::memcpy(out + d_offset + d_size_subchannel_orga_field * subch_count, + d_subchannel_orga_field, + d_size_subchannel_orga_field); + d_offset += d_size_subchannel_orga_field; - //change SubChID, start address, protection level and subch size of each sub channel - //the SubChannel ID has to increase, to be different - bit_adaption(out + d_offset - 26, subch_count, 6); - //the start address (in CUs) of the next subch is increased about size of previous subch - bit_adaption(out + d_offset - 16, d_start_adress, 10); - //protection level - bit_adaption(out + d_offset - 10, d_protection_mode[subch_count], 2); - //calculate size of subchannel in CUs (table 7, p. 51) - switch (d_protection_mode[subch_count]) { - case 0: - d_subch_size = 12 * d_data_rate_n[subch_count]; - break; - case 1: - d_subch_size = 8 * d_data_rate_n[subch_count]; - break; - case 2: - d_subch_size = 6 * d_data_rate_n[subch_count]; - break; - case 3: - d_subch_size = 4 * d_data_rate_n[subch_count]; - break; - default: - //error - break; - } - //write subchannel size - bit_adaption(out + d_offset - 0, d_subch_size, 10); - //shift start address - d_start_adress += d_subch_size; - } - //subchannel orga is set, set EndMarker and padding - if ((8 * FIB_DATA_FIELD_LENGTH) - d_offset >= - 8) {//add EndMarker (111 11111) if there is minimum one byte left in FIG (FIG without 16 bit crc16) - for (int i = 0; i < 8; i++) { //find:: binde FIC.h ein und verwende die konstaten statt FIB_size - out[i + d_offset] = 1; - } - } - d_offset += 8; - while (d_offset % (8 * FIB_LENGTH) != - 0) {//padding (fill rest of FIB with zeroes, as well the last 16 crc bits) - out[d_offset] = 0; - d_offset++; - } - d_nFIBs_written++; - }//second FIB is finished - else { + /* Change SubChID, start address, protection level and + * subch size of each sub channel. + * The SubChannel ID has to increase, to be different. */ + bit_adaption(out + d_offset - 26, subch_count, 6); + /* The start address (in CUs) of the next subch is increased + * about size of previous subch. */ + bit_adaption(out + d_offset - 16, d_start_adress, 10); + // protection level + bit_adaption(out + d_offset - 10, d_protection_mode[subch_count], 2); + // Calculate size of subchannel in CUs. (table 7, p. 51) + switch (d_protection_mode[subch_count]) { + case 0: + d_subch_size = 12 * d_data_rate_n[subch_count]; + break; + case 1: + d_subch_size = 8 * d_data_rate_n[subch_count]; + break; + case 2: + d_subch_size = 6 * d_data_rate_n[subch_count]; + break; + case 3: + d_subch_size = 4 * d_data_rate_n[subch_count]; + break; + default: + //error + break; + } + // write subchannel size + bit_adaption(out + d_offset - 0, d_subch_size, 10); + // shift start address + d_start_adress += d_subch_size; + } + // Subchannel orga is set, set EndMarker and padding. + if ((8 * FIB_DATA_FIELD_LENGTH) - d_offset >= 8) { + /* Add EndMarker (111 11111) if there is minimum one byte left + * in FIG. (FIG without 16 bit crc16) */ + for (int i = 0; i < 8; i++) { + out[i + d_offset] = 1; + } + } + d_offset += 8; + while (d_offset % (8 * FIB_LENGTH) != 0) { + /* Padding. (fill rest of FIB with zeroes, as well the last 16 crc bits) */ + out[d_offset] = 0; + d_offset++; + } + d_nFIBs_written++; + }// second FIB is finished + else { ///////////////////////////////////////////////// /// write a not primary FIB with SI ///////////////////////////////////////////////// - do { //fill FIB with FIGs - if(d_label_counter == 0){ - // write ensemble label - std::memcpy(out + d_offset, d_ensemble_label, d_size_label); - d_offset += d_size_label; - // change country ID - bit_adaption(out + d_offset-(d_size_label-20), d_country_ID, 4); - ++d_label_counter; - } - else{ - // write service label - std::memcpy(out + d_offset, d_programme_service_label, d_size_label); - // change label - std::string label = d_service_labels.substr((d_label_counter-1)*16, 16); - write_label(out + d_offset + 32, label); - d_offset += d_size_label; - bit_adaption(out + d_offset - 144, d_label_counter-1, 8); - if(++d_label_counter > d_num_subch){ - d_label_counter = 0; + do { // Fill FIB with FIGs. + if (d_label_counter == 0) { + // Write ensemble label. + std::memcpy(out + d_offset, d_ensemble_label, d_size_label); + d_offset += d_size_label; + // Change country ID. + bit_adaption(out + d_offset - (d_size_label - 20), d_country_ID, 4); + ++d_label_counter; + } else { + // Write service label. + std::memcpy(out + d_offset, d_programme_service_label, d_size_label); + // Change label. + std::string label = d_service_labels.substr((d_label_counter - 1) * 16, 16); + write_label(out + d_offset + 32, label); + d_offset += d_size_label; + bit_adaption(out + d_offset - 144, d_label_counter - 1, 8); + if (++d_label_counter > d_num_subch) { + d_label_counter = 0; + } + + } + /* Check if there is enough space for next FIG. */ + } while ((8 * FIB_DATA_FIELD_LENGTH) - (d_offset % (8 * FIB_LENGTH)) >= 176); + // FIB is filled, set endmarker and padding. + /* Add EndMarker (111 11111) if there is minimum one byte left in FIG */ + if ((8 * FIB_DATA_FIELD_LENGTH) - (d_offset % (8 * FIB_LENGTH)) >= 8) { + for (int i = 0; i < 8; i++) { + out[i + d_offset] = 1;//padding (fill rest of FIB with zeroes, as well the last 16 crc bits) + } } + d_offset += 8; + // Padding (fill rest of FIB with zeroes, as well the last 16 crc bits). + while (d_offset % (8 * FIB_LENGTH) != 0) { + out[d_offset] = 0; + d_offset++; + } + d_nFIBs_written++; + }// FIB finished. - } - } while ((8 * FIB_DATA_FIELD_LENGTH) - (d_offset % (8 * FIB_LENGTH)) >= 176); //check if there is enough space for next FIG - //FIB is filled, set endmarker and padding - if ((8 * FIB_DATA_FIELD_LENGTH) - (d_offset % (8 * FIB_LENGTH)) >= - 8) {//add EndMarker (111 11111) if there is minimum one byte left in FIG - for (int i = 0; i < 8; i++) { - out[i + d_offset] = 1; - } + } while ((d_nFIBs_written % 3 != 0 && d_transmission_mode != 3) || + (d_nFIBs_written % 4 != 0 && d_transmission_mode == 3)); + // Finished writing a row of FIBs (3 or 4) (number of FIBS for 1 Transmission Frame). + + // Tell runtime system how many output items we produced. + if (d_transmission_mode != 3) { + return 3 * (8 * FIB_LENGTH); } - d_offset += 8; - while (d_offset % (8 * FIB_LENGTH) != - 0) {//padding (fill rest of FIB with zeroes, as well the last 16 crc bits) - out[d_offset] = 0; - d_offset++; + else { + return 4 * (8 * FIB_LENGTH); } - d_nFIBs_written++; - }//FIB finished - - } while ((d_nFIBs_written % 3 != 0 && d_transmission_mode != 3) || (d_nFIBs_written % 4 != 0 && - d_transmission_mode == - 3)); //finished writing a row of FIBs (3 or 4) (number of FIBS for 1 Transmission Frame) - - // Tell runtime system how many output items we produced. - if (d_transmission_mode != 3) return 3 * (8 * FIB_LENGTH); - else return 4 * (8 * FIB_LENGTH); - } + } - } /* namespace dab */ + } /* namespace dab */ } /* namespace gr */ diff --git a/lib/fib_source_b_impl.h b/lib/fib_source_b_impl.h index 6cdb4af4..1cd9ac46 100644 --- a/lib/fib_source_b_impl.h +++ b/lib/fib_source_b_impl.h @@ -25,7 +25,7 @@ namespace gr { namespace dab { -/*! \brief source that produces Fast Information Blocks (FIBs) according to the DAB standard +/*! \brief source that produces Fast Information Blocks (FIBs) according to the DAB standard ETSI EN 300 401 * * output: unpacked byte stream with FIBs (each 256 bit) and zeros at last 16 bits for following CRC16 * @@ -55,7 +55,8 @@ namespace gr { const static char d_ensemble_info[56]; //CIF counter changes every FIB const static int d_size_ensemble_info = 56; - void CIF_counter(char *out_ptr, int counter);//implementation of the mod 20 and mod 250 counter + void CIF_counter(char *out_ptr, + int counter);//implementation of the mod 20 and mod 250 counter const static char d_service_orga_header[16]; //*const const static int d_size_service_orga_header = 16; const static char d_service_orga[40]; //*services @@ -74,12 +75,24 @@ namespace gr { static char d_programme_service_label[176]; //21*8+8, service label (FIG 1/0) std::string d_service_labels; - int write_label(char *out_ptr, std::string label, int num_chars = 16);//default for 16 characters (16 byte) + /*! \brief Writes a character string as utf-8 to byte buffer. + * + * @param out_ptr Pointer to output buffer. + * @param label String object. + * @param num_chars Lenght of the character string (without end indicator). + * @return Number of processed bits (= num_chars * 8). + */ + int write_label(char *out_ptr, std::string label, int num_chars = 16); //default for 16 characters (16 byte) public: - fib_source_b_impl(int transmission_mode, int coutry_ID, int num_subch, std::string ensemble_label, - std::string programme_service_labels, std::string service_comp_label, uint8_t service_comp_lang, - const std::vector &protection_mode, const std::vector &data_rate_n, const std::vector &dabplus); + fib_source_b_impl(int transmission_mode, int coutry_ID, + int num_subch, std::string ensemble_label, + std::string programme_service_labels, + std::string service_comp_label, + uint8_t service_comp_lang, + const std::vector &protection_mode, + const std::vector &data_rate_n, + const std::vector &dabplus); ~fib_source_b_impl(); diff --git a/lib/firecode-checker.cpp b/lib/firecode-checker.cpp index 42e8103b..3261397d 100644 --- a/lib/firecode-checker.cpp +++ b/lib/firecode-checker.cpp @@ -28,10 +28,10 @@ #include // g(x)=(x^11+1)(x^5+x^3+x^2+x+1)=1+x+x^2+x^3+x^5+x^11+x^12+x^13+x^14+x^16 -const uint8_t firecode_checker::g[16] = {1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0}; +const uint8_t firecode_checker::g[16] = {1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 0}; -firecode_checker::firecode_checker(void) -{ +firecode_checker::firecode_checker(void) { // prepare the table uint8_t regs[16]; int16_t i, j; @@ -51,12 +51,10 @@ firecode_checker::firecode_checker(void) } } -firecode_checker::~firecode_checker(void) -{ +firecode_checker::~firecode_checker(void) { } -uint16_t firecode_checker::run8(uint8_t regs[]) -{ +uint16_t firecode_checker::run8(uint8_t regs[]) { int16_t i, j; uint16_t z; uint16_t v = 0; @@ -74,8 +72,7 @@ uint16_t firecode_checker::run8(uint8_t regs[]) return v; } -bool firecode_checker::check(const uint8_t *x) -{ +bool firecode_checker::check(const uint8_t *x) { int16_t i; uint16_t state = (x[2] << 8) | x[3]; uint16_t istate; diff --git a/lib/firecode-checker.h b/lib/firecode-checker.h index 3c2b3050..729b0462 100644 --- a/lib/firecode-checker.h +++ b/lib/firecode-checker.h @@ -27,7 +27,7 @@ #ifndef FIRECODE_CHECKER #define FIRECODE_CHECKER -#include +#include class firecode_checker { diff --git a/lib/firecode_check_bb_impl.cc b/lib/firecode_check_bb_impl.cc index 6a0b1f41..6d505094 100644 --- a/lib/firecode_check_bb_impl.cc +++ b/lib/firecode_check_bb_impl.cc @@ -1,7 +1,10 @@ /* -*- c++ -*- */ /* - * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). - * The class firecode_checker is adapted from the Qt-DAB software, Copyright Jan van Katwijk (Lazy Chair Computing J.vanKatwijk@gmail.com) + * Copyright 2017, 2018 Moritz Luca Schmid, Communications Engineering Lab (CEL) + * Karlsruhe Institute of Technology (KIT). + * + * The class firecode_checker is adapted from the Qt-DAB software + * Copyright Jan van Katwijk (Lazy Chair Computing J.vanKatwijk@gmail.com) * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -36,10 +39,8 @@ namespace gr { namespace dab { firecode_check_bb::sptr - firecode_check_bb::make(int bit_rate_n) - { - return gnuradio::get_initial_sptr - (new firecode_check_bb_impl(bit_rate_n)); + firecode_check_bb::make(int bit_rate_n) { + return gnuradio::get_initial_sptr(new firecode_check_bb_impl(bit_rate_n)); } /* @@ -48,8 +49,7 @@ namespace gr { firecode_check_bb_impl::firecode_check_bb_impl(int bit_rate_n) : gr::block("firecode_check_bb", gr::io_signature::make(1, 1, sizeof(unsigned char)), - gr::io_signature::make(1, 1, sizeof(unsigned char))) - { + gr::io_signature::make(1, 1, sizeof(unsigned char))) { d_frame_size = 24 * bit_rate_n; set_output_multiple(d_frame_size * 5); //logical frame } @@ -57,13 +57,11 @@ namespace gr { /* * Our virtual destructor. */ - firecode_check_bb_impl::~firecode_check_bb_impl() - { + firecode_check_bb_impl::~firecode_check_bb_impl() { } void - firecode_check_bb_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { + firecode_check_bb_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) { ninput_items_required[0] = noutput_items; } @@ -71,8 +69,7 @@ namespace gr { firecode_check_bb_impl::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { const unsigned char *in = (const unsigned char *) input_items[0]; unsigned char *out = (unsigned char *) output_items[0]; d_nproduced = 0; @@ -80,7 +77,6 @@ namespace gr { while (d_nconsumed < noutput_items / d_frame_size - 4) { if (fc.check(&in[d_nconsumed * d_frame_size])) { - GR_LOG_DEBUG(d_logger, format("fire code (%d %d) OK at frame %d") %(int)in[d_nconsumed*d_frame_size] %(int)in[d_nconsumed*d_frame_size+1] % (nitems_read(0) / d_frame_size)); // fire code OK, copy superframe to output memcpy(out + d_nproduced * d_frame_size, in + d_nconsumed * d_frame_size, d_frame_size * 5); d_nproduced += 5; diff --git a/lib/firecode_check_bb_impl.h b/lib/firecode_check_bb_impl.h index b7c74273..cc998c2d 100644 --- a/lib/firecode_check_bb_impl.h +++ b/lib/firecode_check_bb_impl.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * Copyright 2017, 2018 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). * The class firecode_checker is adapted from the Qt-DAB software, Copyright Jan van Katwijk (Lazy Chair Computing J.vanKatwijk@gmail.com) * * This is free software; you can redistribute it and/or modify @@ -28,27 +28,24 @@ namespace gr { namespace dab { /*! \brief checks firecode of logical frames - * - * checks firecode of each logical frame as a qa test for the msc_decoder. - * According to ETSI TS 102 563 every fifth logical frame starts with 16 bit firecode - * - * + * Checks firecode of each logical frame as a qa test for the msc_decoder. + * According to ETSI TS 102 563 every fifth logical frame starts with a 16 bit firecode word. + * @param bit_rate_n data rate in multiples of 8kbit/s */ class firecode_check_bb_impl : public firecode_check_bb { private: - int d_frame_size; - int d_bit_rate_n; - int d_nproduced, d_nconsumed; - bool d_firecode_passed; - firecode_checker fc; + int d_bit_rate_n; /*!< Byte rate. */ + int d_frame_size; /*!< Size in bytes of one transmission frame (depending on bit_rate_n).*/ + int d_nproduced, d_nconsumed; /*!< Control variable for buffer read/write operations. */ + bool d_firecode_passed; /*!< Boolean variable for displaying firecode fails. */ + firecode_checker fc; /*!< Instance of the class firecode_checker. */ public: firecode_check_bb_impl(int bit_rate_n); ~firecode_check_bb_impl(); - virtual bool get_firecode_passed() - { return d_firecode_passed; } + virtual bool get_firecode_passed() { return d_firecode_passed; } // Where all the action really happens void forecast(int noutput_items, gr_vector_int &ninput_items_required); diff --git a/lib/fractional_interpolator_triggered_update_cc_impl.cc b/lib/fractional_interpolator_triggered_update_cc_impl.cc deleted file mode 100644 index 6f85af46..00000000 --- a/lib/fractional_interpolator_triggered_update_cc_impl.cc +++ /dev/null @@ -1,111 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; 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 - -#include - -#include -#include "fractional_interpolator_triggered_update_cc_impl.h" -#include - -namespace gr { - namespace dab { - -fractional_interpolator_triggered_update_cc::sptr -fractional_interpolator_triggered_update_cc::make(float phase_shift, float interp_ratio) -{ - return gnuradio::get_initial_sptr - (new fractional_interpolator_triggered_update_cc_impl(phase_shift, interp_ratio)); -} - -fractional_interpolator_triggered_update_cc_impl::fractional_interpolator_triggered_update_cc_impl(float phase_shift, float interp_ratio) - : gr::block("fractional_interpolator_triggered_update_cc", - gr::io_signature::make2 (2, 2, sizeof (gr_complex), sizeof(char)), - gr::io_signature::make (1, 1, sizeof (gr_complex))), - d_mu (phase_shift), d_mu_inc (interp_ratio), d_next_mu_inc(interp_ratio), d_interp(new gr::filter::mmse_fir_interpolator_cc()) -{ - if (interp_ratio <= 0) - throw std::out_of_range ("interpolation ratio must be > 0"); - if (phase_shift < 0 || phase_shift > 1) - throw std::out_of_range ("phase shift ratio must be > 0 and < 1"); - - set_relative_rate (1.0 / interp_ratio); -} - -fractional_interpolator_triggered_update_cc_impl::~fractional_interpolator_triggered_update_cc_impl() -{ - delete d_interp; -} - -void -fractional_interpolator_triggered_update_cc_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) -{ - unsigned ninputs = ninput_items_required.size(); - for (unsigned i=0; i < ninputs; i++) - - ninput_items_required[i] = - (int) ceil((noutput_items * d_mu_inc) + d_interp->ntaps()); -} - -int -fractional_interpolator_triggered_update_cc_impl::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *in = (const gr_complex *) input_items[0]; - const char *trigger = (const char *) input_items[1]; - gr_complex *out = (gr_complex *) output_items[0]; - - int ii = 0; // input index - int oo = 0; // output index - - while (oo < noutput_items && ii+(int)floor(d_mu+d_mu_inc)interpolate(&in[ii], d_mu); - - double s = d_mu + d_mu_inc; - double f = floor (s); - int incr = (int) f; - d_mu = s - f; - ii += incr; - - for (int i=0; i -#include - -namespace gr { - namespace dab { - -class fractional_interpolator_triggered_update_cc_impl : public fractional_interpolator_triggered_update_cc -{ - public: - fractional_interpolator_triggered_update_cc_impl(float phase_shift, float interp_ratio); - ~fractional_interpolator_triggered_update_cc_impl(); - void forecast(int noutput_items, gr_vector_int &ninput_items_required); - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - - float mu() const { return d_mu;} - float interp_ratio() const { return d_mu_inc;} - void set_mu (float mu) { d_mu = mu; } - void set_interp_ratio (float interp_ratio) { d_next_mu_inc = interp_ratio; } - - - private: - float d_mu; - float d_mu_inc; - float d_next_mu_inc; - gr::filter::mmse_fir_interpolator_cc *d_interp; - -}; - -} -} - -#endif diff --git a/lib/frequency_interleaver_vcc_impl.cc b/lib/frequency_interleaver_vcc_impl.cc index a0f4f3b6..b291f4ee 100644 --- a/lib/frequency_interleaver_vcc_impl.cc +++ b/lib/frequency_interleaver_vcc_impl.cc @@ -35,42 +35,40 @@ namespace gr { namespace dab { -frequency_interleaver_vcc::sptr -frequency_interleaver_vcc::make(const std::vector &interleaving_sequence) -{ - return gnuradio::get_initial_sptr - (new frequency_interleaver_vcc_impl(interleaving_sequence)); -} + frequency_interleaver_vcc::sptr + frequency_interleaver_vcc::make(const std::vector &interleaving_sequence) { + return gnuradio::get_initial_sptr(new frequency_interleaver_vcc_impl(interleaving_sequence)); + } -frequency_interleaver_vcc_impl::frequency_interleaver_vcc_impl(const std::vector &interleaving_sequence) - : gr::sync_block("frequency_interleaver_vcc", - gr::io_signature::make (1, 1, sizeof(gr_complex)*interleaving_sequence.size()), - gr::io_signature::make (1, 1, sizeof(gr_complex)*interleaving_sequence.size())), - d_interleaving_sequence(interleaving_sequence), d_length(interleaving_sequence.size()) -{ - for (unsigned int i=0; i &interleaving_sequence) + : gr::sync_block("frequency_interleaver_vcc", + gr::io_signature::make(1, 1, sizeof(gr_complex) * interleaving_sequence.size()), + gr::io_signature::make(1, 1, sizeof(gr_complex) * interleaving_sequence.size())), + d_interleaving_sequence(interleaving_sequence), + d_length(interleaving_sequence.size()) { + for (unsigned int i = 0; i < d_length; i++) + assert(d_interleaving_sequence[i] < (short) d_length); + } + int + frequency_interleaver_vcc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + gr_complex const *in = (const gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; -int -frequency_interleaver_vcc_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - gr_complex const *in = (const gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; + for (int i = 0; i < noutput_items; i++) { + for (unsigned int j = 0; j < d_length; j++) { + out[d_interleaving_sequence[j]] = in[j]; + } + out += d_length; + in += d_length; + } - for (int i = 0; i < noutput_items; i++) { - for (unsigned int j = 0; j < d_length; j++) - out[d_interleaving_sequence[j]] = in[j]; - out += d_length; - in += d_length; - } - - return noutput_items; -} + return noutput_items; + } -} + } } diff --git a/lib/frequency_interleaver_vcc_impl.h b/lib/frequency_interleaver_vcc_impl.h index 29249c92..771853a0 100644 --- a/lib/frequency_interleaver_vcc_impl.h +++ b/lib/frequency_interleaver_vcc_impl.h @@ -26,23 +26,31 @@ namespace gr { namespace dab { +/*! \brief interleaves vector elements after the rules of a given interleaving sequence + * + * @param interleaving_sequence sequence defining the interleaving rules + */ + class frequency_interleaver_vcc_impl : public frequency_interleaver_vcc { + private: -class frequency_interleaver_vcc_impl : public frequency_interleaver_vcc -{ - private: + std::vector d_interleaving_sequence; + /*!< Vector containing the sequence, which is controlling the interleaving + * of the OFDM sub carriers. */ + unsigned int d_length; /*!< Length of the vector d_interleaving_sequence. */ - std::vector d_interleaving_sequence; - unsigned int d_length; + public: + frequency_interleaver_vcc_impl(const std::vector &interleaving_sequence); - public: - frequency_interleaver_vcc_impl(const std::vector &interleaving_sequence); - void set_sequence(const std::vector &interleaving_sequence) { d_interleaving_sequence = interleaving_sequence; } - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; + void set_sequence(const std::vector &interleaving_sequence) { + d_interleaving_sequence = interleaving_sequence; + } -} + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } } #endif /* INCLUDED_DAB_FREQUENCY_INTERLEAVER_VCC_H */ diff --git a/lib/insert_null_symbol_impl.cc b/lib/insert_null_symbol_impl.cc index 9d5ff5f8..0cacc0f7 100644 --- a/lib/insert_null_symbol_impl.cc +++ b/lib/insert_null_symbol_impl.cc @@ -1,19 +1,20 @@ /* -*- c++ -*- */ /* * Copyright 2004 Free Software Foundation, Inc. - * + * Copyright 2018 Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * * This file is part of GNU Radio - * + * * GNU Radio 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. - * + * * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, @@ -35,78 +36,84 @@ namespace gr { namespace dab { -insert_null_symbol::sptr -insert_null_symbol::make(int ns_length, int symbol_length) -{ - return gnuradio::get_initial_sptr - (new insert_null_symbol_impl(ns_length, symbol_length)); -} + insert_null_symbol::sptr + insert_null_symbol::make(int ns_length, int symbol_length) { + return gnuradio::get_initial_sptr + (new insert_null_symbol_impl(ns_length, symbol_length)); + } -insert_null_symbol_impl::insert_null_symbol_impl(int ns_length, int symbol_length) - : gr::block("insert_null_symbol", - gr::io_signature::make2 (2, 2, sizeof(gr_complex)*symbol_length, sizeof(char)), - gr::io_signature::make (1, 1, sizeof(gr_complex))), - d_ns_length(ns_length), d_symbol_length(symbol_length), d_ns_added(0) -{ - /* note: setting output_multiple to a high value without setting the relative rate produces - * - * gr_vmcircbuf_sysv_shm: shmget (1): Invalid argument - * gr_buffer::allocate_buffer: failed to allocate buffer of size 102080 KB - * terminate called after throwing an instance of 'std::bad_alloc' - * what(): St9bad_alloc - * - * maybe the scheduler thinks that d_symbol_length input items are needed, which uses a lot of memory - **/ - set_output_multiple(d_symbol_length); - set_relative_rate(d_symbol_length); -} + insert_null_symbol_impl::insert_null_symbol_impl(int ns_length, int symbol_length) + : gr::block("insert_null_symbol", + gr::io_signature::make2(2, 2, sizeof(gr_complex) * symbol_length, sizeof(char)), + gr::io_signature::make(1, 1, sizeof(gr_complex))), + d_ns_length(ns_length), d_symbol_length(symbol_length), + d_ns_added(0) { + /* note: setting output_multiple to a high value without setting the relative rate produces + * + * gr_vmcircbuf_sysv_shm: shmget (1): Invalid argument + * gr_buffer::allocate_buffer: failed to allocate buffer of size 102080 KB + * terminate called after throwing an instance of 'std::bad_alloc' + * what(): St9bad_alloc + * + * maybe the scheduler thinks that d_symbol_length input items are needed, which uses a lot of memory + **/ + if (d_symbol_length <= 0){ + throw std::runtime_error("Symbol length must be greater zero!"); + } + set_output_multiple(d_symbol_length); + set_relative_rate(d_symbol_length); + } -void -insert_null_symbol_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) -{ - int in_req = noutput_items / d_symbol_length; - unsigned ninputs = ninput_items_required.size (); - for (unsigned i = 0; i < ninputs; i++) - ninput_items_required[i] = in_req; -} + void + insert_null_symbol_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) { + int in_req = noutput_items / d_symbol_length; + unsigned ninputs = ninput_items_required.size(); + for (unsigned i = 0; i < ninputs; i++) { + ninput_items_required[i] = in_req; + } + } -int -insert_null_symbol_impl::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *iptr = (const gr_complex *) input_items[0]; - const char *trigger = (const char *) input_items[1]; - - gr_complex *optr = (gr_complex *) output_items[0]; + int + insert_null_symbol_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + const gr_complex *iptr = (const gr_complex *) input_items[0]; + const char *trigger = (const char *) input_items[1]; - int produced_items=0; - int consumed_items=0; - int i; - - while (noutput_items-produced_items>=d_symbol_length && consumed_items= d_symbol_length + && consumed_items < ninput_items[0] + && consumed_items < ninput_items[1]) { + if (*trigger == 1 && d_ns_added < d_ns_length) { + for (i = 0; i < d_ns_length - d_ns_added && i < noutput_items - produced_items; i++) { + *optr++ = 0; + } + produced_items += i; + d_ns_added += i; + } else { + if (*trigger == 0) { + d_ns_added = 0; + } + memcpy(optr, iptr, d_symbol_length); + iptr += d_symbol_length; + optr += d_symbol_length; + produced_items += d_symbol_length; + trigger++; + consumed_items++; + } + } + + consume_each(consumed_items); + return produced_items; + } + + } } diff --git a/lib/insert_null_symbol_impl.h b/lib/insert_null_symbol_impl.h index 90acac57..5a88b2b6 100644 --- a/lib/insert_null_symbol_impl.h +++ b/lib/insert_null_symbol_impl.h @@ -26,7 +26,10 @@ namespace gr { namespace dab { - +/*! \brief inserting complex zeros at the beginning of each transmission frame + * @param symbol_length length of the symbol vector + * @param ns_length length of null symbol + */ class insert_null_symbol_impl : public insert_null_symbol { private: diff --git a/lib/magnitude_equalizer_vcc_impl.cc b/lib/magnitude_equalizer_vcc_impl.cc deleted file mode 100644 index d4378e9a..00000000 --- a/lib/magnitude_equalizer_vcc_impl.cc +++ /dev/null @@ -1,116 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "magnitude_equalizer_vcc_impl.h" - -namespace gr { - namespace dab { - -magnitude_equalizer_vcc::sptr -magnitude_equalizer_vcc::make(unsigned int vlen, unsigned int num_symbols) -{ - return gnuradio::get_initial_sptr - (new magnitude_equalizer_vcc_impl(vlen, num_symbols)); -} - -magnitude_equalizer_vcc_impl::magnitude_equalizer_vcc_impl(unsigned int vlen, unsigned int num_symbols) - : gr::sync_block("magnitude_equalizer_vcc", - gr::io_signature::make2 (2, 2, sizeof(gr_complex)*vlen, sizeof(char)), - gr::io_signature::make2 (2, 2, sizeof(gr_complex)*vlen, sizeof(char))), - d_vlen(vlen), d_num_symbols(num_symbols) -{ - assert(d_num_symbols>0); - - d_equalizer = new float[vlen]; - for (unsigned int i=0;i1) { - for (unsigned int i=1; i update equalizer */ - update_equalizer(in); - frame_start_out[i] = 1; - } else { - frame_start_out[i] = 0; - } - - for (unsigned int j=0;j - -namespace gr { - namespace dab { - -class magnitude_equalizer_vcc_impl : public magnitude_equalizer_vcc -{ - private: - void update_equalizer(const gr_complex *in); - - unsigned int d_vlen; - unsigned int d_num_symbols; - float *d_equalizer; - - public: - magnitude_equalizer_vcc_impl(unsigned int vlen, unsigned int num_symbols); - ~magnitude_equalizer_vcc_impl(void); - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -} -} - -#endif /* INCLUDED_DAB_MAGNITUDE_EQUALIZER_VCC_H */ diff --git a/lib/mapper_bc_impl.cc b/lib/mapper_bc_impl.cc deleted file mode 100644 index f720190d..00000000 --- a/lib/mapper_bc_impl.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2017 by Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). - * - * 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 Frank1Llin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "mapper_bc_impl.h" - -namespace gr { - namespace dab { - - mapper_bc::sptr - mapper_bc::make(int symbol_length) - { - return gnuradio::get_initial_sptr - (new mapper_bc_impl(symbol_length)); - } - - /* - * The private constructor - */ - mapper_bc_impl::mapper_bc_impl(int symbol_length) - : gr::block("mapper_bc", - gr::io_signature::make(1, 1, sizeof(char)), - gr::io_signature::make(1, 1, sizeof(gr_complex))), - d_symbol_length(symbol_length) - { - set_output_multiple(symbol_length); - } - - /* - * Our virtual destructor. - */ - mapper_bc_impl::~mapper_bc_impl() - { - } - - void - mapper_bc_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { - ninput_items_required[0] = noutput_items * 2; - } - - int - mapper_bc_impl::general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { - const char *in = (const char *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; - - // for each symbol - for (int i = 0; i < noutput_items / d_symbol_length; i++) { - // for d_symbol_length complex outputs - for (int j = 0; j < d_symbol_length; j++) { - //out[i*2*d_symbol_length + j] = gr_complex(in[(i*2)*d_symbol_length + j], in[(i*2 + 1)*d_symbol_length + j]); - if (in[(i * 2) * d_symbol_length + j] > 0) { - if (in[(i * 2 + 1) * d_symbol_length + j] > 0) - out[i * d_symbol_length + j] = gr_complex(-I_SQRT2, -I_SQRT2); //11 - else - out[i * d_symbol_length + j] = gr_complex(-I_SQRT2, I_SQRT2); //10 - } else { - if (in[(i * 2 + 1) * d_symbol_length + j] > 0) - out[i * d_symbol_length + j] = gr_complex(I_SQRT2, -I_SQRT2); //01 - else - out[i * d_symbol_length + j] = gr_complex(I_SQRT2, I_SQRT2); //00 - } - } - } - // Tell runtime system how many input items we consumed on - // each input stream. - consume_each(noutput_items * 2); - - // Tell runtime system how many output items we produced. - return noutput_items; - } - - } /* namespace dab */ -} /* namespace gr */ - diff --git a/lib/mapper_bc_impl.h b/lib/mapper_bc_impl.h deleted file mode 100644 index 9819cead..00000000 --- a/lib/mapper_bc_impl.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2017 by Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). - * - * 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_DAB_MAPPER_BC_IMPL_H -#define INCLUDED_DAB_MAPPER_BC_IMPL_H - -#define I_SQRT2 0.707106781187 - -#include - -namespace gr { - namespace dab { -/*! \brief QPSK mapper according to the DAB standard ETSI EN 300 401 V1.4.1, clause 14.5 - * - * uses two unpacked bit frames of respectively length symbol_length to form a complex frame of length symbol_length - * two bits define a complex symbol, the first bit is taken from the the first bit frame at index i, the second bit from the second bit frame at index i, they form the complex symbol at index i - * - * @param symbol_length length of output frame - * - */ - class mapper_bc_impl : public mapper_bc { - private: - int d_symbol_length; - - public: - mapper_bc_impl(int symbol_length); - - ~mapper_bc_impl(); - - // Where all the action really happens - void forecast(int noutput_items, gr_vector_int &ninput_items_required); - - int general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_MAPPER_BC_IMPL_H */ - diff --git a/lib/measure_processing_rate_impl.cc b/lib/measure_processing_rate_impl.cc deleted file mode 100644 index 2f943e9e..00000000 --- a/lib/measure_processing_rate_impl.cc +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2006,2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; 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 - -#include - -#include -#include "measure_processing_rate_impl.h" -#include -#include - -namespace gr { - namespace dab { - -measure_processing_rate::sptr -measure_processing_rate::make(size_t itemsize, int samples_to_count) -{ - return gnuradio::get_initial_sptr - (new measure_processing_rate_impl(itemsize, samples_to_count)); -} - -measure_processing_rate_impl::measure_processing_rate_impl(size_t itemsize, int samples_to_count) - : gr::sync_block("measure_processing_rate", - gr::io_signature::make(1, 1, itemsize), - gr::io_signature::make(0, 0, 0)), - d_itemsize(itemsize), d_samples_to_count(samples_to_count), d_count(0), d_processing_rate(0) -{ - if (gettimeofday(&d_time, NULL) != 0) { - perror("dab_measure_processing_rate: gettimeofday"); - exit(-1); - } -} - -int -measure_processing_rate_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - d_count+=noutput_items; - - struct timeval cur_time; - - if (d_count >= d_samples_to_count) { - d_count -= d_samples_to_count; - if (gettimeofday(&cur_time, NULL) != 0) { - perror("dab_measure_processing_rate: gettimeofday"); - exit(-1); - } - d_processing_rate = (float)d_samples_to_count/((float)(cur_time.tv_sec - d_time.tv_sec) + (float)(cur_time.tv_usec - d_time.tv_usec)/1000000); - d_time = cur_time; - // printf("processing rate: %f\n", d_processing_rate); - } - - return noutput_items; -} - -} -} diff --git a/lib/measure_processing_rate_impl.h b/lib/measure_processing_rate_impl.h deleted file mode 100644 index 593b5a95..00000000 --- a/lib/measure_processing_rate_impl.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ -#ifndef INCLUDED_DAB_MEASURE_PROCESSING_RATE_IMPL_H -#define INCLUDED_DAB_MEASURE_PROCESSING_RATE_IMPL_H - -#include - -namespace gr { - namespace dab { - -class measure_processing_rate_impl : public measure_processing_rate -{ - - private: - size_t d_itemsize; - int d_samples_to_count; - int d_count; - struct timeval d_time; - float d_processing_rate; - - public: - measure_processing_rate_impl(size_t itemsize, int samples_to_count); - void set_samples_to_count(int samples_to_count) { d_samples_to_count=samples_to_count; } - /*! \return processing rate in samples per second */ - float processing_rate() { return d_processing_rate; } - /*! \return processing rate in bits per second */ - float bitrate() { return d_itemsize*8*d_processing_rate; } - - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -} -} - -#endif /* INCLUDED_DAB_MEASURE_PROCESSING_RATE_H */ diff --git a/lib/modulo_ff_impl.cc b/lib/modulo_ff_impl.cc deleted file mode 100644 index 69b59c6b..00000000 --- a/lib/modulo_ff_impl.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "modulo_ff_impl.h" -#include - -namespace gr { - namespace dab { - -modulo_ff::sptr -modulo_ff::make(float div) -{ - return gnuradio::get_initial_sptr - (new modulo_ff_impl(div)); -} - -/* - * Specify constraints on number of input and output streams. - * This info is used to construct the input and output signatures - * (2nd & 3rd args to gr_block's constructor). The input and - * output signatures are used by the runtime system to - * check that a valid number and type of inputs and outputs - * are connected to this block. In this case, we accept - * only 1 input and 1 output. - */ -static const int MIN_IN = 1; // mininum number of input streams -static const int MAX_IN = 1; // maximum number of input streams -static const int MIN_OUT = 1; // minimum number of output streams -static const int MAX_OUT = 1; // maximum number of output streams - -/* - * The private constructor - */ -modulo_ff_impl::modulo_ff_impl(float div) - : gr::sync_block("modulo_ff", - gr::io_signature::make (MIN_IN, MAX_IN, sizeof (float)), - gr::io_signature::make (MIN_OUT, MAX_OUT, sizeof (float))), - d_div(div) -{ -} - -/* - * Our virtual destructor. - */ -modulo_ff_impl::~modulo_ff_impl() -{ - // nothing else required in this example -} - -int -modulo_ff_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const float *in = (const float *) input_items[0]; - float *out = (float *) output_items[0]; - - for (int i=0; i < noutput_items; i++) { - *out++ = *in - d_div*floor(*in / d_div); - in++; - } - - // Tell runtime system how many output items we produced. - return noutput_items; -} - -} -} diff --git a/lib/modulo_ff_impl.h b/lib/modulo_ff_impl.h deleted file mode 100644 index 24a7fa1a..00000000 --- a/lib/modulo_ff_impl.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ -#ifndef INCLUDED_DAB_MODULO_FF_IMPL_H -#define INCLUDED_DAB_MODULO_FF_IMPL_H - -#include - -namespace gr { - namespace dab { - -class modulo_ff_impl : public modulo_ff -{ -private: - - float d_div; - - public: - modulo_ff_impl(float div); - ~modulo_ff_impl(); // public destructor - - // Where all the action really happens - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -} -} - -#endif /* INCLUDED_DAB_MODULO_FF_H */ diff --git a/lib/moving_sum_ff_impl.cc b/lib/moving_sum_ff_impl.cc deleted file mode 100644 index 53ef2ed4..00000000 --- a/lib/moving_sum_ff_impl.cc +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "moving_sum_ff_impl.h" - -namespace gr { - namespace dab { -/* - * Create a new instance of dab_moving_sum_ff and return - * a boost shared_ptr. This is effectively the public constructor. - */ -moving_sum_ff::sptr -moving_sum_ff::make(int length) -{ - return gnuradio::get_initial_sptr - (new moving_sum_ff_impl(length)); -} - -/* - * Specify constraints on number of input and output streams. - * This info is used to construct the input and output signatures - * (2nd & 3rd args to gr_block's constructor). The input and - * output signatures are used by the runtime system to - * check that a valid number and type of inputs and outputs - * are connected to this block. In this case, we accept - * only 1 input and 1 output. - */ -static const int MIN_IN = 1; // mininum number of input streams -static const int MAX_IN = 1; // maximum number of input streams -static const int MIN_OUT = 1; // minimum number of output streams -static const int MAX_OUT = 1; // maximum number of output streams - -/* - * The private constructor - */ -moving_sum_ff_impl::moving_sum_ff_impl(int length) - : gr::sync_block("moving_sum_ff", - gr::io_signature::make (MIN_IN, MAX_IN, sizeof (float)), - gr::io_signature::make (MIN_OUT, MAX_OUT, sizeof (float))), - d_sum(0), d_length(length) -{ - assert(length>=0); - set_history(length+1); - set_output_multiple(length+1); -} - -/* - * Our virtual destructor. - */ -moving_sum_ff_impl::~moving_sum_ff_impl() -{ - // nothing else required in this example -} - -int -moving_sum_ff_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const float *in = (const float *) input_items[0]; - float *out = (float *) output_items[0]; - // just so i know, what gnuradio is doing ... - // printf("noutput_items: %d\n", noutput_items); - // for (int j=0; j - -namespace gr { - namespace dab { - -class moving_sum_ff_impl : public moving_sum_ff -{ -private: - - - double d_sum; - int d_length; - - public: - moving_sum_ff_impl(int length); - ~moving_sum_ff_impl(); - int length() const {return d_length;} - void reset() {d_sum=0;} - - // Where all the action really happens - - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -} -} - -#endif /* INCLUDED_DAB_MOVING_SUM_FF_H */ diff --git a/lib/mp2_decode_bs_impl.cc b/lib/mp2_decode_bs_impl.cc index cda9adda..fbd184fb 100644 --- a/lib/mp2_decode_bs_impl.cc +++ b/lib/mp2_decode_bs_impl.cc @@ -1,10 +1,13 @@ /* -*- c++ -*- */ /* -* 2017 by Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). -* A major part of this code is adapted from the kjmp2 library, slightly modified and written into a GNURadio block. -* Note that this is an altered version of kjmp2 and not the original library. -*/ + * 2017 by Moritz Luca Schmid, Communications Engineering Lab (CEL) + * Karlsruhe Institute of Technology (KIT). + * + * A major part of this code is adapted from the kjmp2 library, + * slightly modified and written into a GNURadio block. + * Note that this is an altered version of kjmp2 and not the original library. + */ /****************************************************************************** ** kjmp2 -- a minimal MPEG-1/2 Audio Layer II decoder library ** @@ -72,38 +75,38 @@ namespace gr { // synthesis window static const int D[512] = { - 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, -0x00001, - -0x00001, -0x00001, -0x00001, -0x00002, -0x00002, -0x00003, -0x00003, -0x00004, - -0x00004, -0x00005, -0x00006, -0x00006, -0x00007, -0x00008, -0x00009, -0x0000A, - -0x0000C, -0x0000D, -0x0000F, -0x00010, -0x00012, -0x00014, -0x00017, -0x00019, - -0x0001C, -0x0001E, -0x00022, -0x00025, -0x00028, -0x0002C, -0x00030, -0x00034, - -0x00039, -0x0003E, -0x00043, -0x00048, -0x0004E, -0x00054, -0x0005A, -0x00060, - -0x00067, -0x0006E, -0x00074, -0x0007C, -0x00083, -0x0008A, -0x00092, -0x00099, - -0x000A0, -0x000A8, -0x000AF, -0x000B6, -0x000BD, -0x000C3, -0x000C9, -0x000CF, + 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000, 0x00000,-0x00001, + -0x00001,-0x00001,-0x00001,-0x00002,-0x00002,-0x00003,-0x00003,-0x00004, + -0x00004,-0x00005,-0x00006,-0x00006,-0x00007,-0x00008,-0x00009,-0x0000A, + -0x0000C,-0x0000D,-0x0000F,-0x00010,-0x00012,-0x00014,-0x00017,-0x00019, + -0x0001C,-0x0001E,-0x00022,-0x00025,-0x00028,-0x0002C,-0x00030,-0x00034, + -0x00039,-0x0003E,-0x00043,-0x00048,-0x0004E,-0x00054,-0x0005A,-0x00060, + -0x00067,-0x0006E,-0x00074,-0x0007C,-0x00083,-0x0008A,-0x00092,-0x00099, + -0x000A0,-0x000A8,-0x000AF,-0x000B6,-0x000BD,-0x000C3,-0x000C9,-0x000CF, 0x000D5, 0x000DA, 0x000DE, 0x000E1, 0x000E3, 0x000E4, 0x000E4, 0x000E3, 0x000E0, 0x000DD, 0x000D7, 0x000D0, 0x000C8, 0x000BD, 0x000B1, 0x000A3, - 0x00092, 0x0007F, 0x0006A, 0x00053, 0x00039, 0x0001D, -0x00001, -0x00023, - -0x00047, -0x0006E, -0x00098, -0x000C4, -0x000F3, -0x00125, -0x0015A, -0x00190, - -0x001CA, -0x00206, -0x00244, -0x00284, -0x002C6, -0x0030A, -0x0034F, -0x00396, - -0x003DE, -0x00427, -0x00470, -0x004B9, -0x00502, -0x0054B, -0x00593, -0x005D9, - -0x0061E, -0x00661, -0x006A1, -0x006DE, -0x00718, -0x0074D, -0x0077E, -0x007A9, - -0x007D0, -0x007EF, -0x00808, -0x0081A, -0x00824, -0x00826, -0x0081F, -0x0080E, + 0x00092, 0x0007F, 0x0006A, 0x00053, 0x00039, 0x0001D,-0x00001,-0x00023, + -0x00047,-0x0006E,-0x00098,-0x000C4,-0x000F3,-0x00125,-0x0015A,-0x00190, + -0x001CA,-0x00206,-0x00244,-0x00284,-0x002C6,-0x0030A,-0x0034F,-0x00396, + -0x003DE,-0x00427,-0x00470,-0x004B9,-0x00502,-0x0054B,-0x00593,-0x005D9, + -0x0061E,-0x00661,-0x006A1,-0x006DE,-0x00718,-0x0074D,-0x0077E,-0x007A9, + -0x007D0,-0x007EF,-0x00808,-0x0081A,-0x00824,-0x00826,-0x0081F,-0x0080E, 0x007F5, 0x007D0, 0x007A0, 0x00765, 0x0071E, 0x006CB, 0x0066C, 0x005FF, 0x00586, 0x00500, 0x0046B, 0x003CA, 0x0031A, 0x0025D, 0x00192, 0x000B9, - -0x0002C, -0x0011F, -0x00220, -0x0032D, -0x00446, -0x0056B, -0x0069B, -0x007D5, - -0x00919, -0x00A66, -0x00BBB, -0x00D16, -0x00E78, -0x00FDE, -0x01148, -0x012B3, - -0x01420, -0x0158C, -0x016F6, -0x0185C, -0x019BC, -0x01B16, -0x01C66, -0x01DAC, - -0x01EE5, -0x02010, -0x0212A, -0x02232, -0x02325, -0x02402, -0x024C7, -0x02570, - -0x025FE, -0x0266D, -0x026BB, -0x026E6, -0x026ED, -0x026CE, -0x02686, -0x02615, - -0x02577, -0x024AC, -0x023B2, -0x02287, -0x0212B, -0x01F9B, -0x01DD7, -0x01BDD, + -0x0002C,-0x0011F,-0x00220,-0x0032D,-0x00446,-0x0056B,-0x0069B,-0x007D5, + -0x00919,-0x00A66,-0x00BBB,-0x00D16,-0x00E78,-0x00FDE,-0x01148,-0x012B3, + -0x01420,-0x0158C,-0x016F6,-0x0185C,-0x019BC,-0x01B16,-0x01C66,-0x01DAC, + -0x01EE5,-0x02010,-0x0212A,-0x02232,-0x02325,-0x02402,-0x024C7,-0x02570, + -0x025FE,-0x0266D,-0x026BB,-0x026E6,-0x026ED,-0x026CE,-0x02686,-0x02615, + -0x02577,-0x024AC,-0x023B2,-0x02287,-0x0212B,-0x01F9B,-0x01DD7,-0x01BDD, 0x019AE, 0x01747, 0x014A8, 0x011D1, 0x00EC0, 0x00B77, 0x007F5, 0x0043A, - 0x00046, -0x003E5, -0x00849, -0x00CE3, -0x011B4, -0x016B9, -0x01BF1, -0x0215B, - -0x026F6, -0x02CBE, -0x032B3, -0x038D3, -0x03F1A, -0x04586, -0x04C15, -0x052C4, - -0x05990, -0x06075, -0x06771, -0x06E80, -0x0759F, -0x07CCA, -0x083FE, -0x08B37, - -0x09270, -0x099A7, -0x0A0D7, -0x0A7FD, -0x0AF14, -0x0B618, -0x0BD05, -0x0C3D8, - -0x0CA8C, -0x0D11D, -0x0D789, -0x0DDC9, -0x0E3DC, -0x0E9BD, -0x0EF68, -0x0F4DB, - -0x0FA12, -0x0FF09, -0x103BD, -0x1082C, -0x10C53, -0x1102E, -0x113BD, -0x116FB, - -0x119E8, -0x11C82, -0x11EC6, -0x120B3, -0x12248, -0x12385, -0x12467, -0x124EF, + 0x00046,-0x003E5,-0x00849,-0x00CE3,-0x011B4,-0x016B9,-0x01BF1,-0x0215B, + -0x026F6,-0x02CBE,-0x032B3,-0x038D3,-0x03F1A,-0x04586,-0x04C15,-0x052C4, + -0x05990,-0x06075,-0x06771,-0x06E80,-0x0759F,-0x07CCA,-0x083FE,-0x08B37, + -0x09270,-0x099A7,-0x0A0D7,-0x0A7FD,-0x0AF14,-0x0B618,-0x0BD05,-0x0C3D8, + -0x0CA8C,-0x0D11D,-0x0D789,-0x0DDC9,-0x0E3DC,-0x0E9BD,-0x0EF68,-0x0F4DB, + -0x0FA12,-0x0FF09,-0x103BD,-0x1082C,-0x10C53,-0x1102E,-0x113BD,-0x116FB, + -0x119E8,-0x11C82,-0x11EC6,-0x120B3,-0x12248,-0x12385,-0x12467,-0x124EF, 0x1251E, 0x124F0, 0x12468, 0x12386, 0x12249, 0x120B4, 0x11EC7, 0x11C83, 0x119E9, 0x116FC, 0x113BE, 0x1102F, 0x10C54, 0x1082D, 0x103BE, 0x0FF0A, 0x0FA13, 0x0F4DC, 0x0EF69, 0x0E9BE, 0x0E3DD, 0x0DDCA, 0x0D78A, 0x0D11E, @@ -111,23 +114,23 @@ namespace gr { 0x09271, 0x08B38, 0x083FF, 0x07CCB, 0x075A0, 0x06E81, 0x06772, 0x06076, 0x05991, 0x052C5, 0x04C16, 0x04587, 0x03F1B, 0x038D4, 0x032B4, 0x02CBF, 0x026F7, 0x0215C, 0x01BF2, 0x016BA, 0x011B5, 0x00CE4, 0x0084A, 0x003E6, - -0x00045, -0x00439, -0x007F4, -0x00B76, -0x00EBF, -0x011D0, -0x014A7, -0x01746, + -0x00045,-0x00439,-0x007F4,-0x00B76,-0x00EBF,-0x011D0,-0x014A7,-0x01746, 0x019AE, 0x01BDE, 0x01DD8, 0x01F9C, 0x0212C, 0x02288, 0x023B3, 0x024AD, 0x02578, 0x02616, 0x02687, 0x026CF, 0x026EE, 0x026E7, 0x026BC, 0x0266E, 0x025FF, 0x02571, 0x024C8, 0x02403, 0x02326, 0x02233, 0x0212B, 0x02011, 0x01EE6, 0x01DAD, 0x01C67, 0x01B17, 0x019BD, 0x0185D, 0x016F7, 0x0158D, 0x01421, 0x012B4, 0x01149, 0x00FDF, 0x00E79, 0x00D17, 0x00BBC, 0x00A67, 0x0091A, 0x007D6, 0x0069C, 0x0056C, 0x00447, 0x0032E, 0x00221, 0x00120, - 0x0002D, -0x000B8, -0x00191, -0x0025C, -0x00319, -0x003C9, -0x0046A, -0x004FF, - -0x00585, -0x005FE, -0x0066B, -0x006CA, -0x0071D, -0x00764, -0x0079F, -0x007CF, + 0x0002D,-0x000B8,-0x00191,-0x0025C,-0x00319,-0x003C9,-0x0046A,-0x004FF, + -0x00585,-0x005FE,-0x0066B,-0x006CA,-0x0071D,-0x00764,-0x0079F,-0x007CF, 0x007F5, 0x0080F, 0x00820, 0x00827, 0x00825, 0x0081B, 0x00809, 0x007F0, 0x007D1, 0x007AA, 0x0077F, 0x0074E, 0x00719, 0x006DF, 0x006A2, 0x00662, 0x0061F, 0x005DA, 0x00594, 0x0054C, 0x00503, 0x004BA, 0x00471, 0x00428, 0x003DF, 0x00397, 0x00350, 0x0030B, 0x002C7, 0x00285, 0x00245, 0x00207, 0x001CB, 0x00191, 0x0015B, 0x00126, 0x000F4, 0x000C5, 0x00099, 0x0006F, - 0x00048, 0x00024, 0x00002, -0x0001C, -0x00038, -0x00052, -0x00069, -0x0007E, - -0x00091, -0x000A2, -0x000B0, -0x000BC, -0x000C7, -0x000CF, -0x000D6, -0x000DC, - -0x000DF, -0x000E2, -0x000E3, -0x000E3, -0x000E2, -0x000E0, -0x000DD, -0x000D9, + 0x00048, 0x00024, 0x00002,-0x0001C,-0x00038,-0x00052,-0x00069,-0x0007E, + -0x00091,-0x000A2,-0x000B0,-0x000BC,-0x000C7,-0x000CF,-0x000D6,-0x000DC, + -0x000DF,-0x000E2,-0x000E3,-0x000E3,-0x000E2,-0x000E0,-0x000DD,-0x000D9, 0x000D5, 0x000D0, 0x000CA, 0x000C4, 0x000BE, 0x000B7, 0x000B0, 0x000A9, 0x000A1, 0x0009A, 0x00093, 0x0008B, 0x00084, 0x0007D, 0x00075, 0x0006F, 0x00068, 0x00061, 0x0005B, 0x00055, 0x0004F, 0x00049, 0x00044, 0x0003F, @@ -138,6 +141,7 @@ namespace gr { 0x00002, 0x00002, 0x00001, 0x00001, 0x00001, 0x00001, 0x00001, 0x00001 }; + ///////////// Table 3-B.2: Possible quantization per subband /////////////////// // quantizer lookup, step 1: bitrate classes @@ -165,26 +169,27 @@ namespace gr { // quantizer lookup, step 3: B2 table, subband -> nbal, row index // (upper 4 bits: nbal, lower 4 bits: row index) static - uint8_t quant_lut_step3[3][32] = { + const char quant_lut_step3[3][32] = { // low-rate table (3-B.2c and 3-B.2d) - {0x44, 0x44, // SB 0 - 1 - 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34 // SB 2 - 12 + { 0x44,0x44, // SB 0 - 1 + 0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34 // SB 2 - 12 }, // high-rate table (3-B.2a and 3-B.2b) - {0x43, 0x43, 0x43, // SB 0 - 2 - 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, // SB 3 - 10 - 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, // SB 11 - 22 - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 // SB 23 - 29 + { 0x43,0x43,0x43, // SB 0 - 2 + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, // SB 3 - 10 + 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31, // SB 11 - 22 + 0x20,0x20,0x20,0x20,0x20,0x20,0x20 // SB 23 - 29 }, // MPEG-2 LSR table (B.2 in ISO 13818-3) - {0x45, 0x45, 0x45, 0x45, // SB 0 - 3 - 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, // SB 4 - 10 - 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, // SB 11 - - 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24 // - 29 + { 0x45,0x45,0x45,0x45, // SB 0 - 3 + 0x34,0x34,0x34,0x34,0x34,0x34,0x34, // SB 4 - 10 + 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24, // SB 11 - + 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24 // - 29 } }; -// quantizer lookup, step 4: table row, allocation[] value -> quant table index + + // quantizer lookup, step 4: table row, allocation[] value -> quant table index static const char quant_lut_step4[6][16] = { {0, 1, 2, 17}, @@ -219,8 +224,7 @@ namespace gr { mp2_decode_bs::sptr - mp2_decode_bs::make(int bit_rate_n) - { + mp2_decode_bs::make(int bit_rate_n) { return gnuradio::get_initial_sptr (new mp2_decode_bs_impl(bit_rate_n)); } @@ -231,9 +235,9 @@ namespace gr { mp2_decode_bs_impl::mp2_decode_bs_impl(int bit_rate_n) : gr::block("mp2_decode_bs", gr::io_signature::make(1, 1, sizeof(unsigned char)), - gr::io_signature::make(2, 2, sizeof(int16_t))), /* output is always stereo*/ - d_bit_rate_n(bit_rate_n) - { + gr::io_signature::make(2, 2, + sizeof(int16_t))), /* output is always stereo*/ + d_bit_rate_n(bit_rate_n) { d_bit_rate = d_bit_rate_n * 8; int16_t i, j; @@ -269,15 +273,13 @@ namespace gr { /* * Our virtual destructor. */ - mp2_decode_bs_impl::~mp2_decode_bs_impl() - { + mp2_decode_bs_impl::~mp2_decode_bs_impl() { delete[] d_mp2_frame; } #define valid(x) ((x == 48000) || (x == 24000)) - void mp2_decode_bs_impl::set_samplerate(int32_t rate) - { + void mp2_decode_bs_impl::set_samplerate(int32_t rate) { if (d_baud_rate == rate) return; if (!valid (rate)) @@ -286,29 +288,27 @@ namespace gr { d_baud_rate = rate; } - int32_t mp2_decode_bs_impl::mp2_samplerate(uint8_t *frame) - { + int32_t mp2_decode_bs_impl::mp2_samplerate(uint8_t *frame) { if (!frame) return 0; if ((frame[0] != 0xFF) // no valid syncword? || ((frame[1] & 0xF6) != 0xF4) // no MPEG-1/2 Audio Layer II? || ((frame[2] - 0x10) >= 0xE0)) // invalid bitrate? return 0; - d_sample_rate = sample_rates[(((frame[1] & 0x08) >> 1) ^ 4) // MPEG-1/2 switch - + ((frame[2] >> 2) & 3)]; // actual rate + d_sample_rate = sample_rates[ + (((frame[1] & 0x08) >> 1) ^ 4) // MPEG-1/2 switch + + ((frame[2] >> 2) & 3)]; // actual rate return d_sample_rate; } - struct quantizer_spec *mp2_decode_bs_impl::read_allocation(int sb, int b2_table) - { + struct quantizer_spec * + mp2_decode_bs_impl::read_allocation(int sb, int b2_table) { int table_idx = quant_lut_step3[b2_table][sb]; table_idx = quant_lut_step4[table_idx & 15][get_bits(table_idx >> 4)]; return table_idx ? (&quantizer_table[table_idx - 1]) : 0; } - void mp2_decode_bs_impl::read_samples(struct quantizer_spec *q, - int scalefactor, int *sample) - { + void mp2_decode_bs_impl::read_samples(struct quantizer_spec *q, int scalefactor, int *sample) { int idx, adj, scale; register int val; @@ -347,15 +347,15 @@ namespace gr { val = (adj - sample[idx]) * scale; // step 2: apply scalefactor sample[idx] = (val * (scalefactor >> 12) // upper part - + ((val * (scalefactor & 4095) + 2048) >> 12)) // lower part + + ((val * (scalefactor & 4095) + 2048) + >> 12)) // lower part >> 12; // scale adjust } } #define show_bits(bit_count) (bit_window >> (24 - (bit_count))) - int32_t mp2_decode_bs_impl::get_bits(int32_t bit_count) - { + int32_t mp2_decode_bs_impl::get_bits(int32_t bit_count) { //int32_t result = show_bits (bit_count); int32_t result = bit_window >> (24 - bit_count); @@ -372,8 +372,7 @@ namespace gr { // FRAME DECODE FUNCTION // //////////////////////////////////////////////////////////////////////////////// - int32_t mp2_decode_bs_impl::mp2_decode_frame(uint8_t *frame, int16_t *pcm) - { + int32_t mp2_decode_bs_impl::mp2_decode_frame(uint8_t *frame, int16_t *pcm) { uint32_t bit_rate_index_minus1; uint32_t sampling_frequency; uint32_t padding_bit; @@ -516,10 +515,10 @@ namespace gr { d_scalefactor[1][sb][part] = d_scalefactor[0][sb][part]; } -// coefficient input and reconstruction + // coefficient input and reconstruction for (part = 0; part < 3; ++part) { for (gr = 0; gr < 4; ++gr) { -// read the samples + // read the samples for (sb = 0; sb < bound; ++sb) for (ch = 0; ch < 2; ++ch) read_samples(d_allocation[ch][sb], @@ -538,23 +537,22 @@ namespace gr { for (idx = 0; idx < 3; ++idx) d_sample[ch][sb][idx] = 0; -// synthesis loop + // synthesis loop for (idx = 0; idx < 3; ++idx) { -// shifting step + // shifting step d_V_offs = table_idx = (d_V_offs - 64) & 1023; for (ch = 0; ch < 2; ++ch) { -// matrixing + // matrixing for (i = 0; i < 64; ++i) { sum = 0; for (j = 0; j < 32; ++j) // 8b*15b=23b sum += d_N[i][j] * d_sample[ch][j][idx]; -// intermediate value is 28 bit (23 + 5), clamp to 14b -// + // intermediate value is 28 bit (23 + 5), clamp to 14b d_V[ch][table_idx + i] = (sum + 8192) >> 14; } -// construction of U + // construction of U for (i = 0; i < 8; ++i) for (j = 0; j < 32; ++j) { d_U[(i << 6) + j] @@ -563,11 +561,11 @@ namespace gr { d_V[ch][(table_idx + (i << 7) + j + 96) & 1023]; } -// apply window + // apply window for (i = 0; i < 512; ++i) d_U[i] = (d_U[i] * D[i] + 32) >> 6; -// output samples + // output samples for (j = 0; j < 32; ++j) { sum = 0; for (i = 0; i < 16; ++i) @@ -581,15 +579,14 @@ namespace gr { } } // end of synthesis channel loop } // end of synthesis sub-block loop -// adjust PCM output pointer: decoded 3 * 32 = 96 stereo samples + // adjust PCM output pointer: decoded 3 * 32 = 96 stereo samples pcm += 192; } // decoding of the granule finished } return frame_size; } - void mp2_decode_bs_impl::add_bit_to_mp2(uint8_t *v, uint8_t b, int16_t nm) - { + void mp2_decode_bs_impl::add_bit_to_mp2(uint8_t *v, uint8_t b, int16_t nm) { uint8_t byte = v[nm / 8]; int16_t bitnr = 7 - (nm & 7); uint8_t newbyte = (01 << bitnr); @@ -602,25 +599,27 @@ namespace gr { } void - mp2_decode_bs_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { - ninput_items_required[0] = noutput_items / d_output_size * d_mp2_framesize; + mp2_decode_bs_impl::forecast(int noutput_items, + gr_vector_int &ninput_items_required) { + ninput_items_required[0] = + noutput_items / d_output_size * d_mp2_framesize; } int mp2_decode_bs_impl::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { const unsigned char *in = (const unsigned char *) input_items[0]; // input are unpacked bytes int16_t *out_left = (int16_t *) output_items[0]; int16_t *out_right = (int16_t *) output_items[1]; d_nproduced = 0; - for (int logical_frame_count; logical_frame_count < noutput_items / d_output_size; logical_frame_count++) { + for (int logical_frame_count; logical_frame_count < noutput_items / + d_output_size; logical_frame_count++) { int16_t i, j; - int16_t lf = d_baud_rate == 48000 ? d_mp2_framesize : 2 * d_mp2_framesize; + int16_t lf = + d_baud_rate == 48000 ? d_mp2_framesize : 2 * d_mp2_framesize; uint8_t help[24 * d_bit_rate_n]; int16_t vlength = 24 * d_bit_rate / 8; @@ -629,7 +628,9 @@ namespace gr { for (i = 0; i < d_mp2_framesize; i++) { // decoder is in sync with MPEG frame if (d_mp2_header_OK == 2) { - add_bit_to_mp2(d_mp2_frame, in[logical_frame_count * d_mp2_framesize + i], d_mp2_bit_count++); + add_bit_to_mp2(d_mp2_frame, + in[logical_frame_count * d_mp2_framesize + i], + d_mp2_bit_count++); if (d_mp2_bit_count >= lf) { // prepare buffer for PCM stereo samples int16_t sample_buf[KJMP2_SAMPLES_PER_FRAME * 2]; @@ -637,8 +638,8 @@ namespace gr { if (mp2_decode_frame(d_mp2_frame, sample_buf)) { // write successfully decoded data to output buffer for (int n = 0; n < KJMP2_SAMPLES_PER_FRAME; n++) { - out_left[d_nproduced + n] = sample_buf[n*2]; - out_right[d_nproduced + n] = sample_buf[n*2+1]; + out_left[d_nproduced + n] = sample_buf[n * 2]; + out_right[d_nproduced + n] = sample_buf[n * 2 + 1]; } d_nproduced += KJMP2_SAMPLES_PER_FRAME; GR_LOG_DEBUG(d_logger, "mp2 decoding succeeded"); @@ -650,7 +651,7 @@ namespace gr { d_mp2_bit_count = 0; } } else if (d_mp2_header_OK == 0) { -// apparently , we are not in sync yet + // apparently , we are not in sync yet if (in[logical_frame_count * d_mp2_framesize + i] == 01) { if (++d_mp2_header_count == 12) { d_mp2_bit_count = 0; @@ -658,11 +659,13 @@ namespace gr { add_bit_to_mp2(d_mp2_frame, 1, d_mp2_bit_count++); d_mp2_header_OK = 1; } - }else { + } else { d_mp2_header_count = 0; } } else if (d_mp2_header_OK == 1) { - add_bit_to_mp2(d_mp2_frame, in[logical_frame_count * d_mp2_framesize + i], d_mp2_bit_count++); + add_bit_to_mp2(d_mp2_frame, + in[logical_frame_count * d_mp2_framesize + i], + d_mp2_bit_count++); if (d_mp2_bit_count == 24) { set_samplerate(mp2_samplerate(d_mp2_frame)); d_mp2_header_OK = 2; diff --git a/lib/mp2_decode_bs_impl.h b/lib/mp2_decode_bs_impl.h index 62ca2b7e..2b105690 100644 --- a/lib/mp2_decode_bs_impl.h +++ b/lib/mp2_decode_bs_impl.h @@ -1,10 +1,13 @@ /* -*- c++ -*- */ /* -* 2017 by Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). -* A major part of this code is adapted from the kjmp2 library, slightly modified and written into a GNURadio block. -* Note that this is an altered version of kjmp2 and not the original library. -*/ + * 2017 by Moritz Luca Schmid, Communications Engineering Lab (CEL) + * Karlsruhe Institute of Technology (KIT). + * + * A major part of this code is adapted from the kjmp2 library, + * slightly modified and written into a GNURadio block. + * Note that this is an altered version of kjmp2 and not the original library. + */ /****************************************************************************** ** kjmp2 -- a minimal MPEG-1/2 Audio Layer II decoder library ** @@ -33,9 +36,9 @@ #define INCLUDED_DAB_MP2_DECODE_BS_IMPL_H #include -#include -#include -#include +#include +#include +#include //#include "pad-handler.h" namespace gr { @@ -106,8 +109,7 @@ namespace gr { ~mp2_decode_bs_impl(); - virtual int32_t get_sample_rate() - {return d_sample_rate;} + virtual int32_t get_sample_rate() { return d_sample_rate; } // Where all the action really happens void forecast(int noutput_items, gr_vector_int &ninput_items_required); diff --git a/lib/mp2_encode_sb_impl.cc b/lib/mp2_encode_sb_impl.cc index a0e5fa29..e34d7476 100644 --- a/lib/mp2_encode_sb_impl.cc +++ b/lib/mp2_encode_sb_impl.cc @@ -1,10 +1,13 @@ /* -*- c++ -*- */ /* - * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) + * Karlsruhe Institute of Technology (KIT). * * Code from the following third party modules is used: - * - ODR-AudioEnc, Copyright (C) 2011 Martin Storsjo, (C) 2017 Matthias P. Braendli; Licensed under the Apache License, Version 2.0 (the "License") - * - libtoolame-dab taken from ODR-AudioEnc, derived from TooLAME, licensed under LGPL v2.1 or later. See libtoolame-dab/LGPL.txt. This is built into a shared library. + * - ODR-AudioEnc, Copyright (C) 2011 Martin Storsjo, (C) 2017 Matthias P. Braendli; + * Licensed under the Apache License, Version 2.0 (the "License") + * - libtoolame-dab taken from ODR-AudioEnc, derived from TooLAME, licensed under LGPL v2.1 or later. + * See libtoolame-dab/LGPL.txt. This is built into a shared library. * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,10 +42,8 @@ namespace gr { namespace dab { mp2_encode_sb::sptr - mp2_encode_sb::make(int bit_rate_n, int channels, int sample_rate) - { - return gnuradio::get_initial_sptr - (new mp2_encode_sb_impl(bit_rate_n, channels, sample_rate)); + mp2_encode_sb::make(int bit_rate_n, int channels, int sample_rate) { + return gnuradio::get_initial_sptr(new mp2_encode_sb_impl(bit_rate_n, channels, sample_rate)); } /* @@ -52,13 +53,14 @@ namespace gr { : gr::block("mp2_encode_sb", gr::io_signature::make(channels, channels, sizeof(int16_t)), gr::io_signature::make(1, 1, sizeof(unsigned char))), - d_bit_rate_n(bit_rate_n), d_channels(channels), d_samp_rate(sample_rate) - { - if(init_encoder()){ + d_bit_rate_n(bit_rate_n), d_channels(channels), + d_samp_rate(sample_rate) { + if (init_encoder()) { GR_LOG_DEBUG(d_logger, "libtoolame-dab init succeeded"); } if (!(d_samp_rate == 24000 || d_samp_rate == 48000)) { - throw std::invalid_argument((format("samp_rate must be 24kHz or 48kHz, not %d") % d_samp_rate).str()); + throw std::invalid_argument( + (format("samp_rate must be 24kHz or 48kHz, not %d") % d_samp_rate).str()); } d_input_size = 1152; // output size depends on bitrate and sample_rate, d_output_size is max output size @@ -69,16 +71,14 @@ namespace gr { /* * Our virtual destructor. */ - mp2_encode_sb_impl::~mp2_encode_sb_impl() - { + mp2_encode_sb_impl::~mp2_encode_sb_impl() { } /*! \brief initialization of the libtoolame encoder * * @return true if init succeeded */ - bool mp2_encode_sb_impl::init_encoder() - { + bool mp2_encode_sb_impl::init_encoder() { // initialize int err = toolame_init(); // set samplerate @@ -114,24 +114,21 @@ namespace gr { if (err) { GR_LOG_ERROR(d_logger, "libtoolame-dab init failed"); return false; - } - else{ + } else { return true; } } void - mp2_encode_sb_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { - ninput_items_required[0] = noutput_items*d_input_size/d_output_size; + mp2_encode_sb_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) { + ninput_items_required[0] = noutput_items * d_input_size / d_output_size; } int mp2_encode_sb_impl::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { const int16_t *in_ch1 = (const int16_t *) input_items[0]; unsigned char *out = (unsigned char *) output_items[0]; // input buffer for one MPEG output frame @@ -144,23 +141,25 @@ namespace gr { unsigned char pad_buf[padlen + 1]; int num_out_bytes; - for (int i = 0; i < noutput_items/d_output_size; ++i) { + for (int i = 0; i < noutput_items / d_output_size; ++i) { // write next frame to buffer (1 or 2 channels for mono or stereo respectively) - if (d_channels == 1){ + if (d_channels == 1) { memcpy(input_buffers[0], &in_ch1[d_nconsumed], d_input_size * sizeof(int16_t)); - } - else if(d_channels == 2) { // merge channels if stereo + } else if (d_channels == 2) { // merge channels if stereo const int16_t *in_ch2 = (const int16_t *) input_items[1]; memcpy(input_buffers[0], &in_ch1[d_nconsumed], d_input_size * sizeof(int16_t)); memcpy(input_buffers[1], &in_ch2[d_nconsumed], d_input_size * sizeof(int16_t)); } // encode - num_out_bytes = toolame_encode_frame(input_buffers, pad_buf, padlen, &out[d_nproduced], d_output_size); + num_out_bytes = toolame_encode_frame(input_buffers, pad_buf, padlen, + &out[d_nproduced], d_output_size); // we always consume d_input_size = 1152 samples per channel d_nconsumed += d_input_size; // we only produce an output frame every 4-10 cycles (depends on configuration) d_nproduced += num_out_bytes; - GR_LOG_DEBUG(d_logger, format("Encoded frame successfully: %d consumed, %d produced") %d_nconsumed %num_out_bytes); + GR_LOG_DEBUG(d_logger, + format("Encoded frame successfully: %d consumed, %d produced") % + d_nconsumed % num_out_bytes); } // Tell runtime system how many input items we consumed on diff --git a/lib/mp2_encode_sb_impl.h b/lib/mp2_encode_sb_impl.h index 8d052d1d..35fa7b26 100644 --- a/lib/mp2_encode_sb_impl.h +++ b/lib/mp2_encode_sb_impl.h @@ -1,10 +1,13 @@ /* -*- c++ -*- */ /* - * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) + * Karlsruhe Institute of Technology (KIT). * * Code from the following third party modules is used: - * - ODR-AudioEnc, Copyright (C) 2011 Martin Storsjo, (C) 2017 Matthias P. Braendli; Licensed under the Apache License, Version 2.0 (the "License") - * - libtoolame-dab taken from ODR-AudioEnc, derived from TooLAME, licensed under LGPL v2.1 or later. See libtoolame-dab/LGPL.txt. This is built into a shared library. + * - ODR-AudioEnc, Copyright (C) 2011 Martin Storsjo, (C) 2017 Matthias P. Braendli; + * Licensed under the Apache License, Version 2.0 (the "License") + * - libtoolame-dab taken from ODR-AudioEnc, derived from TooLAME, licensed under LGPL v2.1 or later. + * See libtoolame-dab/LGPL.txt. This is built into a shared library. * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,26 +43,26 @@ namespace gr { * @param sample_rate sample rate of the PCM audio stream * */ - class mp2_encode_sb_impl : public mp2_encode_sb - { - private: + class mp2_encode_sb_impl : public mp2_encode_sb { + private: int d_bit_rate_n, d_channels, d_samp_rate; int d_output_size, d_input_size; int d_nproduced, d_nconsumed; bool init_encoder(); - public: + public: mp2_encode_sb_impl(int bit_rate_n, int channels, int sample_rate); + ~mp2_encode_sb_impl(); // Where all the action really happens - void forecast (int noutput_items, gr_vector_int &ninput_items_required); + void forecast(int noutput_items, gr_vector_int &ninput_items_required); int general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; } // namespace dab diff --git a/lib/mp4_decode_bs_impl.cc b/lib/mp4_decode_bs_impl.cc index 9a74dd08..64549c96 100644 --- a/lib/mp4_decode_bs_impl.cc +++ b/lib/mp4_decode_bs_impl.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * Copyright 2017, 2018 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). * * GNU Radio block written for gr-dab including the following third party elements: * -QT-DAB: classes mp4Processor and faad-decoder except the reed-solomon class @@ -14,12 +14,12 @@ * 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, @@ -44,8 +44,7 @@ namespace gr { namespace dab { mp4_decode_bs::sptr - mp4_decode_bs::make(int bit_rate_n) - { + mp4_decode_bs::make(int bit_rate_n) { return gnuradio::get_initial_sptr (new mp4_decode_bs_impl(bit_rate_n)); } @@ -57,12 +56,12 @@ namespace gr { : gr::block("mp4_decode_bs", gr::io_signature::make(1, 1, sizeof(unsigned char)), gr::io_signature::make(2, 2, sizeof(int16_t))), - d_bit_rate_n(bit_rate_n) - { + d_bit_rate_n(bit_rate_n) { d_superframe_size = bit_rate_n * 110; d_aacInitialized = false; baudRate = 48000; - set_output_multiple(960 * 4); //TODO: right? baudRate*0.12 for output of one superframe + set_output_multiple(960 * + 4); //TODO: right? baudRate*0.12 for output of one superframe aacHandle = NeAACDecOpen(); //memset(d_aac_frame, 0, 960); d_sample_rate = -1; @@ -71,19 +70,17 @@ namespace gr { /* * Our virtual destructor. */ - mp4_decode_bs_impl::~mp4_decode_bs_impl() - { + mp4_decode_bs_impl::~mp4_decode_bs_impl() { } void - mp4_decode_bs_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { + mp4_decode_bs_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) { ninput_items_required[0] = noutput_items; //TODO: how to calculate actual rate? } // returns aac channel configuration - int mp4_decode_bs_impl::get_aac_channel_configuration(int16_t m_mpeg_surround_config, uint8_t aacChannelMode) - { + int mp4_decode_bs_impl::get_aac_channel_configuration( + int16_t m_mpeg_surround_config, uint8_t aacChannelMode) { switch (m_mpeg_surround_config) { case 0: // no surround return aacChannelMode ? 2 : 1; @@ -99,8 +96,7 @@ namespace gr { bool mp4_decode_bs_impl::initialize(uint8_t dacRate, uint8_t sbrFlag, int16_t mpegSurround, - uint8_t aacChannelMode) - { + uint8_t aacChannelMode) { long unsigned int sample_rate; uint8_t channels; /* AudioSpecificConfig structure (the only way to select 960 transform here!) @@ -120,11 +116,8 @@ namespace gr { * support AudioObjectType 29 (PS) */ - int core_sr_index = - dacRate ? (sbrFlag ? 6 : 3) : - (sbrFlag ? 8 : 5); // 24/48/16/32 kHz - int core_ch_config = get_aac_channel_configuration(mpegSurround, - aacChannelMode); + int core_sr_index = dacRate ? (sbrFlag ? 6 : 3) : (sbrFlag ? 8 : 5); // 24/48/16/32 kHz + int core_ch_config = get_aac_channel_configuration(mpegSurround, aacChannelMode); if (core_ch_config == -1) { GR_LOG_ERROR(d_logger, "Unrecognized mpeg surround config (ignored)"); return false; @@ -153,8 +146,7 @@ namespace gr { uint8_t mpegSurround, uint8_t aacChannelMode, int16_t *out_sample1, - int16_t *out_sample2) - { + int16_t *out_sample2) { // copy AU to process it uint8_t au[2 * 960 + 10]; // sure, large enough memcpy(au, v, frame_length); @@ -186,8 +178,7 @@ namespace gr { uint8_t buffer[], int16_t bufferLength, int16_t *out_sample1, - int16_t *out_sample2) - { + int16_t *out_sample2) { int16_t samples; long unsigned int sample_rate; int16_t *outBuffer; @@ -197,8 +188,9 @@ namespace gr { // initialize AAC decoder at the beginning if (!d_aacInitialized) { - if (!initialize(dacRate, sbrFlag, mpegSurround, aacChannelMode)) + if (!initialize(dacRate, sbrFlag, mpegSurround, aacChannelMode)) { return 0; + } d_aacInitialized = true; GR_LOG_DEBUG(d_logger, "AAC initialized"); } @@ -214,15 +206,10 @@ namespace gr { baudRate = sample_rate; } d_sample_rate = sample_rate; - GR_LOG_DEBUG(d_logger, format("bytes consumed %d") % (int) (hInfo.bytesconsumed)); - GR_LOG_DEBUG(d_logger, - format("sample_rate = %d, samples = %d, channels = %d, error = %d, sbr = %d") % sample_rate % - samples % - (int) (hInfo.channels) % (int) (hInfo.error) % (int) (hInfo.sbr)); channels = hInfo.channels; if (hInfo.error != 0) { - fprintf(stderr, "Warning: %s\n", - faacDecGetErrorMessage(hInfo.error)); + GR_LOG_ERROR(d_logger, format("Warning: %s") % + faacDecGetErrorMessage(hInfo.error)); return 0; } @@ -244,7 +231,6 @@ namespace gr { } else GR_LOG_ERROR(d_logger, "Cannot handle these channels -> dump samples"); - GR_LOG_DEBUG(d_logger, format("Produced %d PCM samples (for each channel)") % (samples / 2)); d_nsamples_produced += samples / 2; return samples / 2; } @@ -255,8 +241,7 @@ namespace gr { * @param len length of dataword without the 2 bytes crc at the end * @return true if CRC passed */ - bool mp4_decode_bs_impl::crc16(const uint8_t *msg, int16_t len) - { + bool mp4_decode_bs_impl::crc16(const uint8_t *msg, int16_t len) { int i, j; uint16_t accumulator = 0xFFFF; uint16_t crc; @@ -277,10 +262,8 @@ namespace gr { return (crc ^ accumulator) == 0; } - uint16_t mp4_decode_bs_impl::BinToDec(const uint8_t *data, size_t offset, size_t length) - { - uint32_t output = (*(data + offset / 8) << 16) | ((*(data + offset / 8 + 1)) << 8) | - (*(data + offset / 8 + 2)); // should be big/little endian save + uint16_t mp4_decode_bs_impl::BinToDec(const uint8_t *data, size_t offset, size_t length) { + uint32_t output = (*(data + offset / 8) << 16) | ((*(data + offset / 8 + 1)) << 8) | (*(data + offset / 8 + 2)); output >>= 24 - length - offset % 8; output &= (0xFFFF >> (16 - length)); return static_cast(output); @@ -290,8 +273,7 @@ namespace gr { mp4_decode_bs_impl::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { const unsigned char *in = (const unsigned char *) input_items[0] + d_superframe_size; int16_t *out1 = (int16_t *) output_items[0]; int16_t *out2 = (int16_t *) output_items[1]; @@ -309,7 +291,10 @@ namespace gr { // log header information GR_LOG_DEBUG(d_logger, format("superframe header: dac_rate %d, sbr_flag %d, aac_mode %d, ps_flag %d, surround %d") % - (int) d_dac_rate % (int) d_sbr_flag % (int) d_aac_channel_mode % (int) d_ps_flag % + (int) d_dac_rate % + (int) d_sbr_flag % + (int) d_aac_channel_mode % + (int) d_ps_flag % (int) d_mpeg_surround); switch (2 * d_dac_rate + d_sbr_flag) { @@ -350,26 +335,34 @@ namespace gr { break; } - // each of the d_num_aus AUs of each superframe (110 * d_bit_rate_n packed bytes) is now processed separately + /* Each of the d_num_aus AUs of each superframe (110 * d_bit_rate_n packed bytes) + * is now processed separately. */ for (int i = 0; i < d_num_aus; i++) { int16_t aac_frame_length; // sanity check for the address if (d_au_start[i + 1] < d_au_start[i]) { - throw std::runtime_error("AU start address invalid"); + // throw std::runtime_error("AU start address invalid"); + std::cout << "AU start address invalid" + << "d_au_start[" << i + << "] = " << d_au_start[i] << "; d_au_start[" << (i+1) + << "]=" << d_au_start[i + 1] << std::endl; + continue; // should not happen, the header is firecode checked } aac_frame_length = d_au_start[i + 1] - d_au_start[i] - 2; // sanity check for the aac_frame_length if ((aac_frame_length >= 960) || (aac_frame_length < 0)) { - throw std::out_of_range((boost::format("aac frame length not in range (%d)") % aac_frame_length).str()); + throw std::out_of_range( + (boost::format("aac frame length not in range (%d)") % + aac_frame_length).str()); } // CRC check of each AU (the 2 byte (16 bit) CRC word is excluded in aac_frame_length) if (crc16(&in[n * d_superframe_size + d_au_start[i]], aac_frame_length)) { - GR_LOG_DEBUG(d_logger, format("CRC check of AU %d successful") % i); + //GR_LOG_DEBUG(d_logger, format("CRC check of AU %d successful") % i); // handle proper AU handle_aac_frame(&in[n * d_superframe_size + d_au_start[i]], aac_frame_length, diff --git a/lib/mp4_decode_bs_impl.h b/lib/mp4_decode_bs_impl.h index 45e7a4bb..0f64c629 100644 --- a/lib/mp4_decode_bs_impl.h +++ b/lib/mp4_decode_bs_impl.h @@ -55,7 +55,8 @@ namespace gr { uint16_t BinToDec(const uint8_t *data, size_t offset, size_t length); - int get_aac_channel_configuration(int16_t m_mpeg_surround_config, uint8_t aacChannelMode); + int get_aac_channel_configuration(int16_t m_mpeg_surround_config, + uint8_t aacChannelMode); bool initialize(uint8_t dacRate, uint8_t sbrFlag, @@ -85,8 +86,7 @@ namespace gr { ~mp4_decode_bs_impl(); - virtual int get_sample_rate() - { return d_sample_rate; } + virtual int get_sample_rate() { return d_sample_rate; } // Where all the action really happens void forecast(int noutput_items, gr_vector_int &ninput_items_required); diff --git a/lib/mp4_encode_sb_impl.cc b/lib/mp4_encode_sb_impl.cc index a46028e6..081cf3ed 100644 --- a/lib/mp4_encode_sb_impl.cc +++ b/lib/mp4_encode_sb_impl.cc @@ -1,6 +1,7 @@ /* -*- c++ -*- */ /* - * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) + * Karlsruhe Institute of Technology (KIT). * * Code from the following third party modules is used: * - ODR-AudioEnc, Copyright (C) 2011 Martin Storsjo, (C) 2017 Matthias P. Braendli; Licensed under the Apache License, Version 2.0 (the "License") @@ -41,27 +42,37 @@ namespace gr { namespace dab { mp4_encode_sb::sptr - mp4_encode_sb::make(int bit_rate_n, int channels, int samp_rate, int afterburner) - { - return gnuradio::get_initial_sptr - (new mp4_encode_sb_impl(bit_rate_n, channels, samp_rate, afterburner)); + mp4_encode_sb::make(int bit_rate_n, int channels, int samp_rate, + int afterburner) { + return gnuradio::get_initial_sptr(new mp4_encode_sb_impl(bit_rate_n, + channels, + samp_rate, + afterburner)); } /* * The private constructor */ - mp4_encode_sb_impl::mp4_encode_sb_impl(int bit_rate_n, int channels, int samp_rate, int afterburner) + mp4_encode_sb_impl::mp4_encode_sb_impl(int bit_rate_n, + int channels, + int samp_rate, + int afterburner) : gr::block("mp4_encode_sb", gr::io_signature::make(channels, channels, sizeof(int16_t)), gr::io_signature::make(1, 1, sizeof(unsigned char))), - d_bit_rate_n(bit_rate_n), d_channels(channels), d_samp_rate(samp_rate), d_afterburner(afterburner) - { + d_bit_rate_n(bit_rate_n), + d_channels(channels), + d_samp_rate(samp_rate), + d_afterburner(afterburner) { // check input arguments if (d_bit_rate_n < 1 || d_bit_rate_n > 24) { - throw std::out_of_range((format("bit_rate_n out of range (%d)") % d_bit_rate_n).str()); + throw std::out_of_range( + (format("bit_rate_n out of range (%d)") % d_bit_rate_n).str()); } if (!(d_samp_rate == 32000 || d_samp_rate == 48000)) { - throw std::invalid_argument((format("samp_rate must be 32kHz or 48kHz, not %d") % d_samp_rate).str()); + throw std::invalid_argument( + (format("samp_rate must be 32kHz or 48kHz, not %d") % + d_samp_rate).str()); } // initialize AAC encoder d_aot = AOT_NONE; @@ -69,14 +80,14 @@ namespace gr { GR_LOG_INFO(d_logger, "AAC enc init succeeded"); } else { GR_LOG_ERROR(d_logger, "AAC enc init failed"); - throw std::runtime_error("AAC enc init failed"); + throw std::runtime_error("AAC enc init failed"); } // check encoder status if (aacEncInfo(d_aac_encoder, &info) != AACENC_OK) { GR_LOG_ERROR(d_logger, "Unable to get the encoder info"); - throw std::runtime_error("AAC enc init failed"); + throw std::runtime_error("AAC enc init failed"); } - + // set input size (number of items per channel(in this case one item is a int16_t)) d_input_size = info.frameLength; GR_LOG_INFO(d_logger, format("AAC Encoding: framelen = %d") % info.frameLength); @@ -89,8 +100,7 @@ namespace gr { /* * Our virtual destructor. */ - mp4_encode_sb_impl::~mp4_encode_sb_impl() - { + mp4_encode_sb_impl::~mp4_encode_sb_impl() { aacEncClose(&d_aac_encoder); } @@ -108,8 +118,7 @@ namespace gr { int channels, int sample_rate, int afterburner, - int *aot) - { + int *aot) { // set number of channels CHANNEL_MODE mode; switch (channels) { @@ -135,19 +144,22 @@ namespace gr { if (channels == 2 && d_bit_rate_n <= 6) { *aot = AOT_DABPLUS_PS; GR_LOG_INFO(d_logger, "AOT set to AAC Parametric Stereo"); - } else if ((channels == 1 && d_bit_rate_n <= 8) || (channels == 2 && d_bit_rate_n <= 10)) { + } else if ((channels == 1 && d_bit_rate_n <= 8) || + (channels == 2 && d_bit_rate_n <= 10)) { *aot = AOT_DABPLUS_SBR; - GR_LOG_INFO(d_logger, "AOT set to AAC SBR (Spectral Band Replication)"); + GR_LOG_INFO(d_logger, + "AOT set to AAC SBR (Spectral Band Replication)"); } else { *aot = AOT_DABPLUS_AAC_LC; GR_LOG_INFO(d_logger, "AOT set to AAC LC (Low Complexity)"); } } - GR_LOG_INFO(d_logger, format("Using %d subchannels. channels = %d, sample_rate = %d") - % d_bit_rate_n - % channels - % sample_rate); + GR_LOG_INFO(d_logger, + format("Using %d subchannels. channels = %d, sample_rate = %d") + % d_bit_rate_n + % channels + % sample_rate); // set AAC parameters if (aacEncoder_SetParam(*encoder, AACENC_AOT, *aot) != AACENC_OK) { @@ -180,7 +192,8 @@ namespace gr { return false; } // set aac bit rate - GR_LOG_INFO(d_logger, format("AAC bitrate set to: %d") % (d_bit_rate_n * 8000)); + GR_LOG_INFO(d_logger, + format("AAC bitrate set to: %d") % (d_bit_rate_n * 8000)); if (aacEncoder_SetParam(*encoder, AACENC_BITRATE, d_bit_rate_n * 8000) != AACENC_OK) { GR_LOG_ERROR(d_logger, "Unable to set the bitrate"); return false; @@ -209,9 +222,11 @@ namespace gr { * @param size_output_buffer size of output buffer * @return true if no errors occurred */ - bool mp4_encode_sb_impl::encode(int16_t *input_buffer, int size_input_buffer, unsigned char *output_buffer, - int size_output_buffer) - { + bool + mp4_encode_sb_impl::encode(int16_t *input_buffer, + int size_input_buffer, + unsigned char *output_buffer, + int size_output_buffer) { AACENC_ERROR err; // prepare input buffer @@ -249,20 +264,25 @@ namespace gr { return false; } // if no error occurred we assume everything is fine and dump input frame - nconsumed += out_args.numInSamples / 2; //(each half of numInSamples came from one of the 2 channels) + nconsumed += out_args.numInSamples / + 2; //(each half of numInSamples came from one of the 2 channels) GR_LOG_DEBUG(d_logger, - format("Encoder: consumed %d, produced %d,") % out_args.numInSamples % out_args.numOutBytes); + format("Encoder: consumed %d, produced %d,") % + out_args.numInSamples % out_args.numOutBytes); // buffer check - if (out_args.numInSamples > size_input_buffer || out_args.numOutBytes > size_output_buffer) { - throw std::runtime_error((format("too much samples (%d) to write in ouput buffer (%d samples left)") %out_args.numOutBytes %size_output_buffer).str()); + if (out_args.numInSamples > size_input_buffer || + out_args.numOutBytes > size_output_buffer) { + throw std::runtime_error( + (format("too much samples (%d) to write in ouput buffer (%d samples left)") % + out_args.numOutBytes % + size_output_buffer).str()); } nproduced += out_args.numOutBytes; return true; } void - mp4_encode_sb_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { + mp4_encode_sb_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) { ninput_items_required[0] = noutput_items * d_input_size / d_output_size; ninput_items_required[1] = noutput_items * d_input_size / d_output_size; } @@ -271,8 +291,7 @@ namespace gr { mp4_encode_sb_impl::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { const int16_t *in_ch1 = (const int16_t *) input_items[0]; unsigned char *out = (unsigned char *) output_items[0]; int16_t input_buffer[d_input_size * 2]; @@ -282,18 +301,17 @@ namespace gr { nproduced = 0; do { // copy frame to buffer - if (d_channels == 1){ + if (d_channels == 1) { memcpy(input_buffer, &in_ch1[nconsumed], d_input_size * sizeof(int16_t)); - } - else if(d_channels == 2) { // merge channels if stereo + } else if (d_channels == 2) { // merge channels if stereo const int16_t *in_ch2 = (const int16_t *) input_items[1]; for (int i = 0; i < d_input_size; ++i) { input_buffer[2 * i] = in_ch1[nconsumed + i]; input_buffer[2 * i + 1] = in_ch2[nconsumed + i]; } } - // send filled buffer to encoder - encode(input_buffer, d_input_size * d_channels, &out[nproduced], noutput_items - nproduced); // encode input stream + // send filled buffer to encoder and encode input stream + encode(input_buffer, d_input_size * d_channels, &out[nproduced], noutput_items - nproduced); } while (nproduced < noutput_items / d_output_size); // Tell runtime system how many input items we consumed on diff --git a/lib/mp4_encode_sb_impl.h b/lib/mp4_encode_sb_impl.h index 037d5a5b..5437d16e 100644 --- a/lib/mp4_encode_sb_impl.h +++ b/lib/mp4_encode_sb_impl.h @@ -1,6 +1,7 @@ /* -*- c++ -*- */ /* - * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) + * Karlsruhe Institute of Technology (KIT). * * Code from the following third party modules is used: * - ODR-AudioEnc, Copyright (C) 2011 Martin Storsjo, (C) 2017 Matthias P. Braendli; Licensed under the Apache License, Version 2.0 (the "License") @@ -37,33 +38,36 @@ namespace gr { * @param bit_rate_n data rate in multiples of 8kbit/s * @param channels number of input audio channels */ - class mp4_encode_sb_impl : public mp4_encode_sb - { - private: + class mp4_encode_sb_impl : public mp4_encode_sb { + private: int d_bit_rate_n, d_channels, d_samp_rate, d_afterburner, d_aot; int nconsumed, nproduced; int d_input_size, d_output_size; HANDLE_AACENCODER d_aac_encoder; - AACENC_InfoStruct info = { 0 }; + AACENC_InfoStruct info = {0}; bool init_aac_encoder(HANDLE_AACENCODER *encoder, int channels, int sample_rate, int afterburner, int *aot); - bool encode(int16_t *input_buffer, int size_input_buffer, unsigned char *output_buffer, int size_output_buffer); - public: - mp4_encode_sb_impl(int bit_rate_n, int channels, int samp_rate, int afterburner); + bool encode(int16_t *input_buffer, int size_input_buffer, + unsigned char *output_buffer, int size_output_buffer); + + public: + mp4_encode_sb_impl(int bit_rate_n, int channels, int samp_rate, + int afterburner); + ~mp4_encode_sb_impl(); // Where all the action really happens - void forecast (int noutput_items, gr_vector_int &ninput_items_required); + void forecast(int noutput_items, gr_vector_int &ninput_items_required); int general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; } // namespace dab diff --git a/lib/ofdm_coarse_frequency_correct_impl.cc b/lib/ofdm_coarse_frequency_correct_impl.cc deleted file mode 100644 index 940dac51..00000000 --- a/lib/ofdm_coarse_frequency_correct_impl.cc +++ /dev/null @@ -1,152 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include "ofdm_coarse_frequency_correct_impl.h" -#include - -#define M_TWOPI (2*M_PI) - -namespace gr { - namespace dab { - -ofdm_coarse_frequency_correct::sptr -ofdm_coarse_frequency_correct::make(unsigned int fft_length, unsigned int num_carriers, unsigned int cp_length) -{ - return gnuradio::get_initial_sptr - (new ofdm_coarse_frequency_correct_impl(fft_length, num_carriers, cp_length)); -} - -ofdm_coarse_frequency_correct_impl::ofdm_coarse_frequency_correct_impl(unsigned int fft_length, unsigned int num_carriers, unsigned int cp_length) - : gr::sync_block("ofdm_coarse_frequency_correct", - gr::io_signature::make2 (2, 2, sizeof(gr_complex)*fft_length, sizeof(char)), - gr::io_signature::make2 (2, 2, sizeof(gr_complex)*num_carriers, sizeof(char))), - d_fft_length(fft_length), d_num_carriers(num_carriers), d_cp_length(cp_length), - d_symbol_num(0), d_freq_offset(0), d_delta_f(0) -{ - d_zeros_on_left = (d_fft_length-d_num_carriers)/2; -} - -float -ofdm_coarse_frequency_correct_impl::mag_squared(const gr_complex sample) { - const float __x = sample.real(); - const float __y = sample.imag(); - return __x * __x + __y * __y; -} - -void -ofdm_coarse_frequency_correct_impl::correlate_energy(const gr_complex *symbol) -{ - unsigned int i, index; - - double sum=0, max=0; - - /* energy based correlation - note that DAB uses a zero central carrier - - * we always sum up the energy for all carriers except DC; this is however - * only done for the first offset; for the others, the diff is calculated - */ - - /* offset 0 */ - for (i=0; i max) { - max = sum; - index = i; - } - } - - d_freq_offset = index; -} - -int -ofdm_coarse_frequency_correct_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - unsigned int i; - gr_complex phase_offset_correct; - - /* partially adapted from gr_ofdm_frame_acquisition.cc - however: - - energy based offset frequency estimation instead of using the pilot symbol - - correlation in linear time instead of sqare - - only magnitude equalisation (phase equalisation is unnecessery, because of the diff_phasor later in the chain) - - calculation of the magnitude scale factors is done in the same step as the calculation of the energy for the freq. offset estimation -> very efficient :) - */ - const gr_complex *iptr = (const gr_complex *) input_items[0]; - const char *frame_start = (const char *) input_items[1]; - - gr_complex *optr = (gr_complex *) output_items[0]; - char *frame_start_out = (char *) output_items[1]; - - if (frame_start[0]) { - frame_start_out[0] = 1; - correlate_energy(iptr); - d_delta_f = d_freq_offset+d_num_carriers/2-d_fft_length/2; - // fprintf(stderr, "cfs: coarse freq. offset (subcarriers): %d\n", d_delta_f); - d_symbol_num = 0; - } else { - frame_start_out[0] = 0; - d_symbol_num++; - } - - /* correct phase offset from removing cp */ - /* could be done after diff phasor, then it would be the same offset for each symbol; but its hardly much of an overhead */ - phase_offset_correct = gr_expj(-M_TWOPI*(float)d_delta_f*(float)d_cp_length/(float)d_fft_length * (float)d_symbol_num); - - for (i=0;i - -namespace gr { - namespace dab { - -class ofdm_coarse_frequency_correct_impl : public ofdm_coarse_frequency_correct -{ - private: - - float mag_squared(const gr_complex sample); - void correlate_energy(const gr_complex *symbol); - - unsigned int d_fft_length; - unsigned int d_num_carriers; - unsigned int d_cp_length; - unsigned int d_symbol_num; - unsigned int d_zeros_on_left; - unsigned int d_freq_offset; - int d_delta_f; - - public: - ofdm_coarse_frequency_correct_impl(unsigned int fft_length, unsigned int num_carriers, unsigned int cp_length); - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -} -} - -#endif /* INCLUDED_DAB_OFDM_COARSE_FREQUENCY_CORRECT_H */ diff --git a/lib/ofdm_coarse_frequency_correction_vcvc_impl.cc b/lib/ofdm_coarse_frequency_correction_vcvc_impl.cc new file mode 100644 index 00000000..a046aab4 --- /dev/null +++ b/lib/ofdm_coarse_frequency_correction_vcvc_impl.cc @@ -0,0 +1,181 @@ +/* -*- c++ -*- */ +/* + * Copyright 2017, 2018 Moritz Luca Schmid, Communications Engineering Lab (CEL) + * Karlsruhe Institute of Technology (KIT). + * + * 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 + +#include +#include "ofdm_coarse_frequency_correction_vcvc_impl.h" +#include +#include + +namespace gr { + namespace dab { + + ofdm_coarse_frequency_correction_vcvc::sptr + ofdm_coarse_frequency_correction_vcvc::make(int fft_length, + int num_carriers, + int cyclic_prefix_length) { + return gnuradio::get_initial_sptr( + new ofdm_coarse_frequency_correction_vcvc_impl(fft_length, + num_carriers, + cyclic_prefix_length)); + } + + /* + * The private constructor + */ + ofdm_coarse_frequency_correction_vcvc_impl::ofdm_coarse_frequency_correction_vcvc_impl( + int fft_length, int num_carriers, int cyclic_prefix_length) + : gr::sync_block("ofdm_coarse_frequency_correction_vcvc", + gr::io_signature::make(1, 1, fft_length * sizeof(gr_complex)), + gr::io_signature::make(1, 1, num_carriers * sizeof(gr_complex))), + d_fft_length(fft_length), + d_num_carriers(num_carriers), + d_cyclic_prefix_length(cyclic_prefix_length), + d_freq_offset(0), + d_snr(0) { + unsigned int alignment = volk_get_alignment(); + d_mag_squared = (float *) volk_malloc(sizeof(float) * num_carriers + 1, alignment); + } + /* + * Our virtual destructor. + */ + ofdm_coarse_frequency_correction_vcvc_impl::~ofdm_coarse_frequency_correction_vcvc_impl() { + } + + /*! Energy measurement over the num_carriers sub_carriers + the central carrier. + * The energy gets a maximum when the calculation window and the occupied carriers are congruent. + * Fine frequency synchronization in the range of one sub-carrier spacing is already done. + */ + void + ofdm_coarse_frequency_correction_vcvc_impl::measure_energy(const gr_complex *symbol) { + unsigned int i, index; + float energy = 0, max = 0; + // first energy measurement is processed completely + volk_32fc_magnitude_squared_32f(d_mag_squared, symbol, d_num_carriers + 1); + volk_32f_accumulator_s32f(&energy, d_mag_squared, d_num_carriers + 1); + // subtract the central (DC) carrier which is not occupied + energy -= std::real(symbol[d_num_carriers]) * std::real(symbol[d_num_carriers]) + + std::imag(symbol[d_num_carriers]) * std::imag(symbol[d_num_carriers]); + max = energy; + index = 0; + /* the energy measurements with all possible carrier offsets are calculated over a moving sum, + * searching for a maximum of energy + */ + for (i = 1; i < d_fft_length - d_num_carriers; i++) { + /* diff on left side */ + energy -= std::real(symbol[i - 1]) * std::real(symbol[i - 1]) + + std::imag(symbol[i - 1]) * std::imag(symbol[i - 1]); + /* diff for zero carrier */ + energy += std::real(symbol[i + d_num_carriers / 2 - 1]) * std::real(symbol[i + d_num_carriers / 2 - 1]) + + std::imag(symbol[i + d_num_carriers / 2 - 1]) * std::imag(symbol[i + d_num_carriers / 2 - 1]); + energy -= std::real(symbol[i + d_num_carriers / 2]) * std::real(symbol[i + d_num_carriers / 2]) + + std::imag(symbol[i + d_num_carriers / 2]) * std::imag(symbol[i + d_num_carriers / 2]); + /* diff on rigth side */ + energy += std::real(symbol[i + d_num_carriers]) * std::real(symbol[i + d_num_carriers]) + + std::imag(symbol[i + d_num_carriers]) * std::imag(symbol[i + d_num_carriers]); + /* new max found? */ + if (energy > max) { + max = energy; + index = i; + } + } + d_freq_offset = index; + } + + /*! SNR measurement by comparing the energy of occupied sub-carriers with the ones of empty sub-carriers + * @return estimated SNR float value + */ + void + ofdm_coarse_frequency_correction_vcvc_impl::measure_snr(const gr_complex *symbol) { + // measure normalized energy of occupied sub-carriers + float energy = 0; + volk_32fc_magnitude_squared_32f(d_mag_squared, &symbol[d_freq_offset], d_num_carriers + 1); + volk_32f_accumulator_s32f(&energy, d_mag_squared, d_num_carriers + 1); + // subtract the central (DC) carrier which is not assigned + energy -= std::real(symbol[d_num_carriers + d_freq_offset]) * std::real(symbol[d_num_carriers + d_freq_offset]) + + std::imag(symbol[d_num_carriers + d_freq_offset]) * std::imag(symbol[d_num_carriers + d_freq_offset]); + + // measure normalized energy of empty sub-carriers + float noise_left = 0, noise_right, noise_total; + // empty sub-carriers on left side + volk_32fc_magnitude_squared_32f(d_mag_squared, symbol, d_freq_offset); + volk_32f_accumulator_s32f(&noise_left, d_mag_squared, d_freq_offset); + // empty sub-carriers on right side + volk_32fc_magnitude_squared_32f(d_mag_squared, + &symbol[d_freq_offset + d_num_carriers + 1], + d_fft_length - d_num_carriers - d_freq_offset - 1); + volk_32f_accumulator_s32f(&noise_right, + d_mag_squared, + d_fft_length - d_num_carriers - d_freq_offset - 1); + // add noise energies from both sides to total noise + noise_total = noise_left + noise_right; + noise_total += std::real(symbol[d_freq_offset + d_num_carriers / 2]) * std::real(symbol[d_freq_offset + d_num_carriers / 2]) + + std::imag(symbol[d_freq_offset + d_num_carriers / 2]) * std::imag(symbol[d_freq_offset + d_num_carriers / 2]); + + // normalize + energy = energy / d_num_carriers; + noise_total = noise_total / (d_fft_length - d_num_carriers); + // check if ratio is in the definition range of the log + if (energy > noise_total) { + // now we can calculate the SNR in dB + d_snr = 10 * log10((energy - noise_total) / noise_total); + } + } + + int + ofdm_coarse_frequency_correction_vcvc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + const gr_complex *in = (const gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + std::vector tags; + unsigned int tag_count = 0; + // get tags for the beginning of a frame + get_tags_in_window(tags, 0, 0, noutput_items); + for (int i = 0; i < noutput_items; ++i) { + /* new calculation for each new frame, measured at the pilot symbol and frequency correction + * applied for all symbols of this frame + */ + if (tag_count < tags.size() && + tags[tag_count].offset - nitems_read(0) - i == 0) { + measure_energy(&in[i * d_fft_length]); + measure_snr(&in[i * d_fft_length]); + tag_count++; + } + // copy the first half (left of central sub-carrier) of the sub-carriers to the output + memcpy(out, &in[i * d_fft_length + d_freq_offset], d_num_carriers / 2 * sizeof(gr_complex)); + // copy the second half (right of central sub-carrier) of the sub-carriers to the output + memcpy(out + d_num_carriers / 2, + &in[i * d_fft_length + d_freq_offset + d_num_carriers / 2 + 1], + d_num_carriers / 2 * sizeof(gr_complex)); + out += d_num_carriers; + } + + // Tell runtime system how many output items we produced. + return noutput_items; + } + + } /* namespace dab */ +} /* namespace gr */ + diff --git a/lib/ofdm_coarse_frequency_correction_vcvc_impl.h b/lib/ofdm_coarse_frequency_correction_vcvc_impl.h new file mode 100644 index 00000000..e2490476 --- /dev/null +++ b/lib/ofdm_coarse_frequency_correction_vcvc_impl.h @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2017, 2018 Moritz Luca Schmid, Communications Engineering Lab (CEL) + * Karlsruhe Institute of Technology (KIT). + * + * 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_DAB_OFDM_COARSE_FREQUENCY_CORRECTION_VCVC_IMPL_H +#define INCLUDED_DAB_OFDM_COARSE_FREQUENCY_CORRECTION_VCVC_IMPL_H + +#include + +namespace gr { + namespace dab { +/*! \brief coarse frequency correction on multiples of the sub-carrier spacing + * synchronization on sub-carriers for DAB/DAB+ by energy measurements of the sub-carriers + * + * @param fft_length length of the applied FFT; corresponding to the input vector length + * @param num_carriers number of occupied carriers; corresponding to the output vector length + * @param cyclic_prefix_length length of the cyclic prefix; corresponding to the length of the energy measurement + */ + class ofdm_coarse_frequency_correction_vcvc_impl : public ofdm_coarse_frequency_correction_vcvc { + private: + int d_fft_length; + int d_num_carriers; + int d_cyclic_prefix_length; + float *d_mag_squared; + unsigned int d_freq_offset; /*!< measured position of the first occupied sub-carrier*/ + float d_snr; /*!< measured snr*/ + + public: + ofdm_coarse_frequency_correction_vcvc_impl(int fft_length, + int num_carriers, + int cyclic_prefix_length); + + ~ofdm_coarse_frequency_correction_vcvc_impl(); + + void measure_energy(const gr_complex *); + + void measure_snr(const gr_complex *); + + virtual float get_snr() { return d_snr; } + + // Where all the action really happens + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace dab +} // namespace gr + +#endif /* INCLUDED_DAB_OFDM_COARSE_FREQUENCY_CORRECTION_VCVC_IMPL_H */ + diff --git a/lib/ofdm_ffe_all_in_one_impl.cc b/lib/ofdm_ffe_all_in_one_impl.cc deleted file mode 100644 index 07bfe88c..00000000 --- a/lib/ofdm_ffe_all_in_one_impl.cc +++ /dev/null @@ -1,155 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include -#include "ofdm_ffe_all_in_one_impl.h" -#include - -namespace gr { - namespace dab { -/* - * Create a new instance of dab_ofdm_ffe_all_in_one and return - * a boost shared_ptr. This is effectively the public constructor. - */ -ofdm_ffe_all_in_one::sptr -ofdm_ffe_all_in_one::make(unsigned int symbol_length, unsigned int fft_length, unsigned int num_symbols, float alpha, unsigned int sample_rate) -{ - return gnuradio::get_initial_sptr - (new ofdm_ffe_all_in_one_impl(symbol_length, fft_length, num_symbols, alpha, sample_rate)); -} - -ofdm_ffe_all_in_one_impl::ofdm_ffe_all_in_one_impl(unsigned int symbol_length, unsigned int fft_length, unsigned int num_symbols, float alpha, unsigned int sample_rate) - : gr::sync_block("ofdm_ffe_all_in_one", - gr::io_signature::make2 (2, 2, sizeof(gr_complex), sizeof(char)), - gr::io_signature::make (1, 1, sizeof(float))), - d_symbol_length(symbol_length), d_fft_length(fft_length), d_num_symbols(num_symbols), d_alpha(alpha), d_sample_rate(sample_rate), d_cur_symbol(num_symbols), d_cur_sample(0), d_ffs_error_sum(0), d_estimated_error(0), d_estimated_error_per_sample(0) -{ - assert(symbol_length<=2*fft_length); /* cyclic prefix can not be longer than fft_length .. */ - set_history(symbol_length+1); -} - -float -ofdm_ffe_all_in_one_impl::calc_ffe_estimate(const gr_complex *in) { - gr_complex sum = 0; - int cp_length = d_symbol_length - d_fft_length; - - // for (int i=-cp_length;i<0;i++) - // sum += in[i-d_fft_length+d_symbol_length] * conj(in[i+d_symbol_length]); - for (int i=0;i0) { - if (d_ffs_error_sum < 0 && new_estimate > 0 && new_estimate - d_ffs_error_sum/d_cur_symbol > M_PI) - new_estimate -= 2*M_PI; - else if (d_ffs_error_sum > 0 && new_estimate < 0 && d_ffs_error_sum/d_cur_symbol - new_estimate > M_PI) - new_estimate += 2*M_PI; - } - - d_ffs_error_sum += new_estimate; - } - - if (d_cur_symbol == d_num_symbols-1) { /* update estimated error */ - d_ffs_error_sum /= d_num_symbols; /* average */ - - /* if the offset is close to half of the subcarrier bandwidth, it may - * jump from some large positive value to some large negative value. - * with averaging, this is a problem - we have to detect it (although - * it really only makes a difference when the offset is very close to - * half the subcarrier bandwidth) - - * note: if there is an offset of one subcarrier bandwidth, the phase - * offset in fft_length samples is 2pi */ - if (d_estimated_error < 0 && d_ffs_error_sum > 0 && d_ffs_error_sum - d_estimated_error > M_PI) { - fprintf(stderr, "ofdm_ffe_all_in_one: switch detected: neg -> pos\n"); - d_estimated_error += 2*M_PI; - } else if (d_estimated_error > 0 && d_ffs_error_sum < 0 && d_estimated_error - d_ffs_error_sum > M_PI) { - fprintf(stderr, "ofdm_ffe_all_in_one: switch detected: pos -> neg\n"); - d_estimated_error -= 2*M_PI; - } - - /* the following distinction is not really needed; but without it, - * simulation would need to run much longer, because the - * synchronisation would need time to adjust to the offset */ - if (d_estimated_error == 0) - d_estimated_error = d_ffs_error_sum; /* first time -> fast adjustment */ - else - d_estimated_error = d_alpha*d_ffs_error_sum + (1-d_alpha)*d_estimated_error; /* slow adjustment */ - - d_estimated_error_per_sample = d_estimated_error / (float)d_fft_length; -// fprintf(stderr, "ofdm_ffe_all_in_one: d_estimated_error: %f (%3.2f Hz)\n", d_estimated_error, d_estimated_error_per_sample*d_sample_rate/(2*M_PI)); - } - - d_cur_symbol++; - } - - d_cur_sample++; - - *optr++ = d_estimated_error_per_sample; - iptr++; - } - - return noutput_items; -} - -} -} diff --git a/lib/ofdm_ffe_all_in_one_impl.h b/lib/ofdm_ffe_all_in_one_impl.h deleted file mode 100644 index 35cdfe0c..00000000 --- a/lib/ofdm_ffe_all_in_one_impl.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ -#ifndef INCLUDED_DAB_OFDM_FFE_ALL_IN_ONE_IMPL_H -#define INCLUDED_DAB_OFDM_FFE_ALL_IN_ONE_IMPL_H - -#include - -namespace gr { - namespace dab { - -/*! - * \brief calculates fine frequency error estimation and averages it - * \ingroup DAB - * \param symbol_length number of samples in an OFDM symbol - * \param fft_length number of samples in an OFDM symbol without the cyclic prefix - * \param num_symbols number of symbols to use for averaging (more symbols is better, but symbols towards the end of the frame tend to have larger time offsets and worse values) - * \param alpha how fast should we adapt to new FFS error values (1=immediately) - * \param sample_rate sampling rate - needed to calculate the offset estimation in Hz - * - * input: port 0: complex - actual data; port 1: byte - trigger signal indicating the start of a frame - * output: float fine frequency offset estimation (in radian per sample) - * - * this is an all in one version of ffe in ofdm_sync_dab.py, because the flow graph does not allow to only calculate the estimation when its needed - */ -class ofdm_ffe_all_in_one_impl : public ofdm_ffe_all_in_one -{ - private: - - float calc_ffe_estimate(const gr_complex *iptr); - - unsigned int d_symbol_length; // length of a symbol in samples - unsigned int d_fft_length; // length of a symbol without cyclic prefix in samples - unsigned int d_num_symbols; // number of symbols per frame to average over - float d_alpha; // adjustment speed factor - unsigned int d_sample_rate; // sample rate -- only needed to print the ffs error in Hz - - unsigned int d_cur_symbol; // which symbol in the frame is currently under observation? - unsigned int d_cur_sample; // which sample in the symbol is currently under observation? - float d_ffs_error_sum; // sum of error samples in current frame - float d_estimated_error; // total estimated error - float d_estimated_error_per_sample; // total estimated error / fft_length - - public: - ofdm_ffe_all_in_one_impl (unsigned int symbol_length, unsigned int fft_length, unsigned int num_symbols, float alpha, unsigned int sample_rate); - /*! \return fine frequency error estimate in Hz */ - float ffe_estimate() { return d_estimated_error_per_sample*d_sample_rate/(2*M_PI); } - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -} -} - -#endif /* INCLUDED_DAB_OFDM_FFE_ALL_IN_ONE_H */ diff --git a/lib/ofdm_insert_pilot_vcc_impl.cc b/lib/ofdm_insert_pilot_vcc_impl.cc index 1a044d5f..8ea8434a 100644 --- a/lib/ofdm_insert_pilot_vcc_impl.cc +++ b/lib/ofdm_insert_pilot_vcc_impl.cc @@ -35,65 +35,62 @@ namespace gr { namespace dab { -ofdm_insert_pilot_vcc::sptr -ofdm_insert_pilot_vcc::make(const std::vector &pilot) -{ - return gnuradio::get_initial_sptr - (new ofdm_insert_pilot_vcc_impl(pilot)); -} + ofdm_insert_pilot_vcc::sptr + ofdm_insert_pilot_vcc::make(const std::vector &pilot) { + return gnuradio::get_initial_sptr + (new ofdm_insert_pilot_vcc_impl(pilot)); + } -ofdm_insert_pilot_vcc_impl::ofdm_insert_pilot_vcc_impl(const std::vector &pilot) - : gr::block("ofdm_insert_pilot_vcc", - gr::io_signature::make2 (2, 2, sizeof(gr_complex)*pilot.size(), sizeof(char)), - gr::io_signature::make2 (2, 2, sizeof(gr_complex)*pilot.size(), sizeof(char))), - d_pilot(pilot), d_start(0) -{ -} + ofdm_insert_pilot_vcc_impl::ofdm_insert_pilot_vcc_impl( + const std::vector &pilot) + : gr::block("ofdm_insert_pilot_vcc", + gr::io_signature::make2(2, 2, sizeof(gr_complex) * pilot.size(), sizeof(char)), + gr::io_signature::make2(2, 2, sizeof(gr_complex) * pilot.size(), sizeof(char))), + d_pilot(pilot), d_start(0) { + } -void -ofdm_insert_pilot_vcc_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) -{ - unsigned ninputs = ninput_items_required.size (); - for (unsigned int i = 0; i < ninputs; i++) - ninput_items_required[i] = noutput_items; -} + void + ofdm_insert_pilot_vcc_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) { + unsigned ninputs = ninput_items_required.size(); + for (unsigned int i = 0; i < ninputs; i++) { + ninput_items_required[i] = noutput_items; + } + } -int -ofdm_insert_pilot_vcc_impl::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *iptr = (const gr_complex *) input_items[0]; - const char *frame_start = (const char *) input_items[1]; - - gr_complex *optr = (gr_complex *) output_items[0]; - char *o_frame_start = (char *) output_items[1]; + int + ofdm_insert_pilot_vcc_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + const gr_complex *iptr = (const gr_complex *) input_items[0]; + const char *frame_start = (const char *) input_items[1]; - int n_produced = 0; - int n_consumed = 0; + gr_complex *optr = (gr_complex *) output_items[0]; + char *o_frame_start = (char *) output_items[1]; - for ( ; n_consumed d_pilot; - char d_start; - - public: - ofdm_insert_pilot_vcc_impl(const std::vector &pilot); - void forecast (int noutput_items, gr_vector_int &ninput_items_required); - - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; -} + class ofdm_insert_pilot_vcc_impl : public ofdm_insert_pilot_vcc { + + private: + std::vector d_pilot; + char d_start; + + public: + ofdm_insert_pilot_vcc_impl(const std::vector &pilot); + + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + } } #endif /* INCLUDED_DAB_OFDM_INSERT_PILOT_VCC_H */ diff --git a/lib/ofdm_move_and_insert_zero_impl.cc b/lib/ofdm_move_and_insert_zero_impl.cc index 72c491d2..78bf8530 100644 --- a/lib/ofdm_move_and_insert_zero_impl.cc +++ b/lib/ofdm_move_and_insert_zero_impl.cc @@ -35,55 +35,54 @@ namespace gr { namespace dab { -ofdm_move_and_insert_zero::sptr -ofdm_move_and_insert_zero::make(unsigned int fft_length,unsigned int num_carriers) -{ - return gnuradio::get_initial_sptr - (new ofdm_move_and_insert_zero_impl(fft_length, num_carriers)); -} + ofdm_move_and_insert_zero::sptr + ofdm_move_and_insert_zero::make(unsigned int fft_length, + unsigned int num_carriers) { + return gnuradio::get_initial_sptr(new ofdm_move_and_insert_zero_impl(fft_length, + num_carriers)); + } -ofdm_move_and_insert_zero_impl::ofdm_move_and_insert_zero_impl(unsigned int fft_length,unsigned int num_carriers) - : gr::sync_block("ofdm_move_and_insert_zero", - gr::io_signature::make (1, 1, sizeof(gr_complex)*num_carriers), - gr::io_signature::make (1, 1, sizeof(gr_complex)*fft_length)), - d_fft_length(fft_length), d_num_carriers(num_carriers) -{ - d_zeros_on_left = (d_fft_length-d_num_carriers)/2; -} + ofdm_move_and_insert_zero_impl::ofdm_move_and_insert_zero_impl( + unsigned int fft_length, unsigned int num_carriers) + : gr::sync_block("ofdm_move_and_insert_zero", + gr::io_signature::make(1, 1, sizeof(gr_complex) * num_carriers), + gr::io_signature::make(1, 1, sizeof(gr_complex) * fft_length)), + d_fft_length(fft_length), d_num_carriers(num_carriers) { + d_zeros_on_left = (d_fft_length - d_num_carriers) / 2; + } -int -ofdm_move_and_insert_zero_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - int i; - unsigned int j,k; - /* partially adapted from gr_ofdm_frame_acquisition.cc */ - const gr_complex *in = (const gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; + int + ofdm_move_and_insert_zero_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + int i; + unsigned int j, k; + /* partially adapted from gr_ofdm_frame_acquisition.cc */ + const gr_complex *in = (const gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; - for (i=0; i -#include "ofdm_remove_first_symbol_vcc_impl.h" - -namespace gr { - namespace dab { - -ofdm_remove_first_symbol_vcc::sptr -ofdm_remove_first_symbol_vcc::make(unsigned int vlen) -{ - return gnuradio::get_initial_sptr - (new ofdm_remove_first_symbol_vcc_impl(vlen)); -} - -ofdm_remove_first_symbol_vcc_impl::ofdm_remove_first_symbol_vcc_impl(unsigned int vlen) - : gr::block("ofdm_remove_first_symbol_vcc", - gr::io_signature::make2 (2, 2, sizeof(gr_complex)*vlen, sizeof(char)), - gr::io_signature::make2 (2, 2, sizeof(gr_complex)*vlen, sizeof(char))), - d_vlen(vlen), d_start(0) -{ -} - -void -ofdm_remove_first_symbol_vcc_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) -{ - //int in_req = noutput_items; + 1 + noutput_items/76; // at most every 76th symbol is thrown away (depends on the DAB mode) - int in_req = noutput_items; // altough more may be needed, try to produce output even with only one input - if it's a pilot, we can just consume it ... - unsigned ninputs = ninput_items_required.size (); - for (unsigned int i = 0; i < ninputs; i++) - ninput_items_required[i] = in_req; -} - - -int -ofdm_remove_first_symbol_vcc_impl::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *iptr = (const gr_complex *) input_items[0]; - const char *frame_start = (const char *) input_items[1]; - - gr_complex *optr = (gr_complex *) output_items[0]; - char *o_frame_start = (char *) output_items[1]; - - int n_consumed = 0; - int n_produced = 0; - - for (n_consumed=0; n_consumed - -namespace gr { - namespace dab { -class ofdm_remove_first_symbol_vcc_impl : public ofdm_remove_first_symbol_vcc -{ - private: - - unsigned int d_vlen; - char d_start; - - public: - ofdm_remove_first_symbol_vcc_impl(unsigned int vlen); - void forecast (int noutput_items, gr_vector_int &ninput_items_required); - - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -} -} -#endif /* INCLUDED_DAB_OFDM_REMOVE_FIRST_SYMBOL_VCC_H */ - diff --git a/lib/ofdm_sampler_impl.cc b/lib/ofdm_sampler_impl.cc deleted file mode 100644 index 3b2ce479..00000000 --- a/lib/ofdm_sampler_impl.cc +++ /dev/null @@ -1,136 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "ofdm_sampler_impl.h" - -namespace gr { - namespace dab { - -ofdm_sampler::sptr -ofdm_sampler::make(unsigned int fft_length, unsigned int cp_length, unsigned int symbols_per_frame,unsigned int gap) -{ - return gnuradio::get_initial_sptr - (new ofdm_sampler_impl(fft_length, cp_length, symbols_per_frame, gap)); -} - -ofdm_sampler_impl::ofdm_sampler_impl(unsigned int fft_length, unsigned int cp_length, unsigned int symbols_per_frame,unsigned int gap) - : gr::block("ofdm_sampler", - gr::io_signature::make2 (2, 2, sizeof(gr_complex), sizeof(char)), - gr::io_signature::make2 (2, 2, sizeof(gr_complex)*fft_length, sizeof(char))), - d_state(STATE_NS), d_pos(0), d_fft_length(fft_length), d_cp_length(cp_length), d_symbols_per_frame(symbols_per_frame), d_sym_nr(0), d_gap(gap), d_gap_left(0) -{ - assert(gap<=cp_length); - set_relative_rate(1/float(fft_length+cp_length)); -} - -void -ofdm_sampler_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) -{ - int in_req = d_fft_length+d_cp_length-d_gap; - // int in_req = noutput_items * d_fft_length; - unsigned ninputs = ninput_items_required.size (); - for (unsigned i = 0; i < ninputs; i++) - ninput_items_required[i] = in_req; - // printf("dab_ofdm_sampler forecast: noutput_items: %d in_req: %d\n", noutput_items, in_req); -} - - -int -ofdm_sampler_impl::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - /* partially adapted from gr_ofdm_sampler.cc */ - const gr_complex *iptr = (const gr_complex *) input_items[0]; - const char *trigger = (const char *) input_items[1]; - - gr_complex *optr = (gr_complex *) output_items[0]; - char *outsig = (char *) output_items[1]; - - unsigned int n_in = (ninput_items[0] 0 && index - -namespace gr { - namespace dab { - -/*! - * \brief cuts stream of DAB samples into symbol vectors - * \ingroup DAB - * \param fft_length length of the output vectors - number of samples per symbol without cyclic prefix - * \param cp_length lengith of the cyclic prefix - * \param symbols_per_frame number of symbols in a DAB frame, without Null symbol - * \param gap If the gap is > 0, leave a gap at the end of the symbol, i.e. return some of the cyclic prefix instead of the end of the symbol - * - * input: port 0: complex - actual data; port 1: byte stream with trigger signal indicating the start of a frame - * output: port 0: complex vectors - sampled data; port 1: byte stream with trigger signal indicating the start of a frame - */ -class ofdm_sampler_impl : public ofdm_sampler -{ - private: - - enum state_t {STATE_NS, STATE_CP, STATE_SYM}; - - state_t d_state; - unsigned int d_pos; // position inside OFDM symbol - unsigned int d_fft_length; - unsigned int d_cp_length; - unsigned int d_symbols_per_frame; // total number of symbols in a DAB frame - unsigned int d_sym_nr; // number of symbol inside DAB frame - unsigned int d_gap; // gap from next symbol -> if gap>0: sample before end of frame - unsigned int d_gap_left; // gap left to next symbol? - - public: - ofdm_sampler_impl(unsigned int fft_length, unsigned int cp_length, unsigned int symbols_per_frame,unsigned int gap); - void forecast (int noutput_items, gr_vector_int &ninput_items_required); - - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -} -} - -#endif /* INCLUDED_DAB_OFDM_SAMPLER_H */ diff --git a/lib/ofdm_synchronization_cvf_impl.cc b/lib/ofdm_synchronization_cvf_impl.cc new file mode 100644 index 00000000..91d0cea3 --- /dev/null +++ b/lib/ofdm_synchronization_cvf_impl.cc @@ -0,0 +1,278 @@ +/* -*- c++ -*- */ +/* + * Copyright 2017, 2018 Moritz Luca Schmid, Communications Engineering Lab (CEL) + * Karlsruhe Institute of Technology (KIT). + * Copyright 2018 Communications Engineering Lab (CEL) Karlsruhe Institute of Technology (KIT). + * + * 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 + +#include "ofdm_synchronization_cvf_impl.h" +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace boost; + +namespace gr { + namespace dab { + + ofdm_synchronization_cvf::sptr + ofdm_synchronization_cvf::make(int symbol_length, int cyclic_prefix_length, + int fft_length, int symbols_per_frame) { + return gnuradio::get_initial_sptr(new ofdm_synchronization_cvf_impl(symbol_length, + cyclic_prefix_length, + fft_length, + symbols_per_frame)); + } + + /* + * The private constructor + */ + ofdm_synchronization_cvf_impl::ofdm_synchronization_cvf_impl( + int symbol_length, int cyclic_prefix_length, + int fft_length, int symbols_per_frame) + : gr::block("ofdm_synchronization_cvf", + gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(1, 1, sizeof(gr_complex))), + d_symbol_length(symbol_length), + d_cyclic_prefix_length(cyclic_prefix_length), + d_symbols_per_frame(symbols_per_frame), + d_fft_length(fft_length), + d_correlation(0), + d_energy_prefix(1), + d_energy_repetition(1), + d_frequency_offset_per_sample(0), + d_NULL_detected(false), + d_moving_average_counter(0), + d_symbol_count(0), + d_symbol_element_count(0), + d_wait_for_NULL(true), + d_on_triangle(false), + d_phase(gr_complex(1,0)), + d_peak_set(false), + d_correlation_maximum(0){ + //allocation for repeating energy measurements + unsigned int alignment = volk_get_alignment(); + d_mag_squared = (float *) volk_malloc(sizeof(float) * d_cyclic_prefix_length, alignment); + d_fixed_lag_corr = (gr_complex *) volk_malloc(sizeof(gr_complex) * d_cyclic_prefix_length, alignment); + this->set_output_multiple(d_symbol_length); + } + + /* + * Our virtual destructor. + */ + ofdm_synchronization_cvf_impl::~ofdm_synchronization_cvf_impl() { + } + + void + ofdm_synchronization_cvf_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) { + ninput_items_required[0] = noutput_items + d_symbol_length + d_cyclic_prefix_length + 1; + } + + void + ofdm_synchronization_cvf_impl::delayed_correlation(const gr_complex *sample, bool new_calculation) { + if (d_moving_average_counter > 100000 || d_moving_average_counter == 0 || new_calculation) { + if (d_moving_average_counter == 0 && (!new_calculation)) { + // first value is calculated completely, next values are calculated with moving average + d_moving_average_counter++; + } else { + // reset counter + d_moving_average_counter = 0; + } + // calculate delayed correlation for this sample completely + volk_32fc_x2_conjugate_dot_prod_32fc(d_fixed_lag_corr, sample, + &sample[d_symbol_length], + d_cyclic_prefix_length); + d_correlation = 0; + for (int i = 0; i < d_cyclic_prefix_length; ++i) { + d_correlation += d_fixed_lag_corr[i]; + } + // calculate energy of cyclic prefix for this sample completely + volk_32fc_magnitude_squared_32f(d_mag_squared, sample, d_cyclic_prefix_length); + volk_32f_accumulator_s32f(&d_energy_prefix, d_mag_squared, d_cyclic_prefix_length); + // calculate energy of its repetition for this sample completely + volk_32fc_magnitude_squared_32f(d_mag_squared, &sample[d_symbol_length], d_cyclic_prefix_length); + volk_32f_accumulator_s32f(&d_energy_repetition, d_mag_squared, d_cyclic_prefix_length); + } else { + // calculate next step for moving average + d_correlation += sample[d_cyclic_prefix_length - 1] * conj(sample[d_symbol_length + d_cyclic_prefix_length - 1]); + d_energy_prefix += std::real(sample[d_cyclic_prefix_length - 1] * conj(sample[d_cyclic_prefix_length - 1])); + d_energy_repetition += std::real( sample[d_symbol_length + d_cyclic_prefix_length - 1] * + conj(sample[d_symbol_length + d_cyclic_prefix_length - 1])); + d_correlation -= sample[0] * conj(sample[d_symbol_length]); + d_energy_prefix -= std::real(sample[0] * conj(sample[0])); + d_energy_repetition -= std::real(sample[d_symbol_length] * conj(sample[d_symbol_length])); + d_moving_average_counter++; + } + // normalize + d_correlation_normalized = d_correlation / std::sqrt(d_energy_prefix * d_energy_repetition); + // calculate magnitude + d_correlation_normalized_magnitude = d_correlation_normalized.real() * d_correlation_normalized.real() + + d_correlation_normalized.imag() * d_correlation_normalized.imag(); + } + + /*! \brief returns true at a point with a little space before the peak of a correlation triangular + * + */ + bool + ofdm_synchronization_cvf_impl::detect_start_of_symbol() { + if (d_on_triangle) { + if (d_correlation_normalized_magnitude > d_correlation_maximum) { + d_correlation_maximum = d_correlation_normalized_magnitude; + } + if (d_correlation_normalized_magnitude < d_correlation_maximum - 0.05 && !d_peak_set) { + // we are right behind the peak + d_peak_set = true; + return true; + } + if (d_correlation_normalized_magnitude < 0.25) { + d_peak_set = false; + d_on_triangle = false; + d_correlation_maximum = 0; + } else { + // we are still on the triangle but have not reached the end + return false; + } + } else { + // not on a correlation triangle yet + if (d_correlation_normalized_magnitude > 0.35) { + // now we are on the triangle + d_on_triangle = true; + return false; + } else { + // no triangle here + return false; + } + } + } + + int + ofdm_synchronization_cvf_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + // Initialize this run of work + const gr_complex *in = (const gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + d_nwritten = 0; + + for (int i = 0; i < noutput_items; ++i) { + // just for measurement reasons + if (d_wait_for_NULL) { + // acquisition mode: search for next correlation peak after a NULL symbol + delayed_correlation(&in[i], false); + if (detect_start_of_symbol()) { + if (d_NULL_detected) { + // calculate new frequency offset + d_frequency_offset_per_sample = std::arg(d_correlation) / d_fft_length; // in rad/sample + /* The start of the first symbol after the NULL symbol has been detected. The ideal start to copy + * the symbol is &in[i+d_cyclic_prefix_length] to minimize ISI. + */ + //reset the symbol element counter + d_symbol_element_count = 0; + d_symbol_count = 0; + // reset NULL detector + d_NULL_detected = false; + // switch to tracking mode + d_wait_for_NULL = false; + } else { + //peak but not after NULL symbol + d_NULL_detected = false; + } + } else { + if (((!d_NULL_detected) && (d_energy_prefix / d_energy_repetition < 0.4))) { + // NULL symbol detection, if energy is < 0.4 * energy a symbol time later + d_NULL_detected = true; + } + } + } else { // tracking mode + if (d_symbol_element_count >= (d_symbol_length + d_cyclic_prefix_length)) { + // we expect the start of a new symbol here or the a NULL symbol if we arrived at the end of the frame + d_symbol_count++; + // next symbol expecting + // reset symbol_element_count because we arrived at the start of the next symbol + d_symbol_element_count = 0; + // check if we arrived at the next NULL symbol + if (d_symbol_count >= d_symbols_per_frame) { + d_symbol_count = 0; + //TODO: skip forward more to safe computing many computing steps + // switch to acquisition mode again to get the start of the next frame exactly + d_wait_for_NULL = true; + } else { + // we expect the start of a new symbol here + // correlation has to be calculated completely new, because of skipping samples before + delayed_correlation(&in[i], true); + // check if there is really a peak + if (d_correlation_normalized_magnitude > 0.3) { //TODO: check if we are on right edge + d_frequency_offset_per_sample = std::arg(d_correlation) / d_fft_length; // in rad/sample + } else { + // no peak found -> out of track; search for next NULL symbol + d_wait_for_NULL = true; + GR_LOG_DEBUG(d_logger, + format("Lost track at %d, switching ot acquisition mode (%d)") % + d_symbol_count % + d_correlation_normalized_magnitude); + } + } + } else if (d_symbol_element_count == (3 * d_cyclic_prefix_length)/4){ + // No full OFDM symbol in the input left + if (noutput_items - i < d_symbol_length || ninput_items[0] - i < d_symbol_length) { + this->consume_each(i); + return d_nwritten; + } else { + d_phase *= + std::polar(float(1.0), + static_cast(d_cyclic_prefix_length * + d_frequency_offset_per_sample)); + if (d_symbol_count == 0) { + this->add_item_tag(0, this->nitems_written(0) + d_nwritten + d_cyclic_prefix_length - d_symbol_element_count, + pmt::mp("Start"), + pmt::from_float(std::arg(d_correlation))); + } + volk_32fc_s32fc_x2_rotator_32fc( + &out[d_nwritten], &in[i], + std::polar(float(1.0), d_frequency_offset_per_sample), + &d_phase, d_symbol_length); + d_nwritten += d_symbol_length; + d_symbol_element_count += d_symbol_length - 1; + i += d_symbol_length - 1; + } + } + d_symbol_element_count++; + } + /* fine frequency correction: + * The frequency offset estimation is done above with the correlation. + * The modulated frequency runs parallel to the whole input stream, + * including the cyclic prefix, and is mixed + * to the output symbol samples. + */ + } + consume_each(noutput_items); + return d_nwritten; + } + + } /* namespace dab */ +} /* namespace gr */ diff --git a/lib/ofdm_synchronization_cvf_impl.h b/lib/ofdm_synchronization_cvf_impl.h new file mode 100644 index 00000000..84ee5ae8 --- /dev/null +++ b/lib/ofdm_synchronization_cvf_impl.h @@ -0,0 +1,141 @@ +/* -*- c++ -*- */ +/* + * Copyright 2017, 2018 Moritz Luca Schmid, Communications Engineering Lab (CEL) + * Karlsruhe Institute of Technology (KIT). + * + * 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_DAB_OFDM_SYNCHRONIZATION_CVF_IMPL_H +#define INCLUDED_DAB_OFDM_SYNCHRONIZATION_CVF_IMPL_H + +#include + +namespace gr { + namespace dab { +/*! \brief Sets tag at the beginning of each OFDM frame. + * Lets only pass the one OFDM frames (without the NULL symbol), which + * were detected completely. + * + * \param symbol_length Length of each OFDM symbol without guard intervall. + * \param cyclic_prefix_length Length of the cyclic prefix. (= length of the guard intervall) + * \param fft_length Length of the FFT vector. + * \param symbols_per_frame Number of OFDM symbols without the NULL symbol. + * + */ + class ofdm_synchronization_cvf_impl : public ofdm_synchronization_cvf { + private: + int d_symbol_length; /*!< Length of each OFDM symbol without guard intervall. */ + int d_cyclic_prefix_length; /*!< Length of the cyclic prefix. (= length of the guard intervall) */ + int d_fft_length; /*!< Length of the FFT vector.*/ + int d_moving_average_counter; + /*!< Counts the number of steps the moving average did, to reset it + * from time to time to avoid value drifting caused by float rounding.*/ + gr_complex d_correlation; + /*!< Fixed lag correlation (not normalized) with the lag length + * equal to the cyclic prefix length. + */ + gr_complex d_correlation_normalized; + /*!< Normalized version of d_correlation. The normalization value + * is the mean energy of the correlation sequence, averaged between the + * two parts of the correlation. + */ + float *d_mag_squared; + /*!< Allocated buffer for volk function. + * We write the calculated magnitued squared samples to this buffer to + * accumulate them in the next step. + */ + gr_complex *d_fixed_lag_corr; + /*!< Allocated buffer for volk function. + * We write the calculated correlation samples to this buffer\ + * accumulate them in the next step. + */ + float d_correlation_normalized_magnitude; + /*!< Magnitude of the current fixed correlation value.*/ + float d_correlation_normalized_phase; + /*!< Phase of the current fixed correlation value. */ + float d_energy_prefix; + /*!< Energy of the upcoming cyclic_prefix_length samples. This value + * is used for normalization and NULL symbol detection. + */ + float d_energy_repetition; + /*!< Energy of cyclic_prefix_length samplex, starting symbol_length + * samples from the current sample. This value is used for normalization + * and NULL symbol detection. When we are at the beginning of a OFDM symbol, + * this is equal to the energy of the cyclic prefix. + */ + float d_frequency_offset_per_sample; + /*!< Frequency offset, described as a phase shift per sample. (in rad/sample)*/ + bool d_NULL_detected; + /*!< Signalizes if we recently detected a NULL symbol and + * therefore expect the first symbol of the next frame now. + */ + int d_symbols_per_frame; + /*!< Number of OFDM symbols without the NULL symbol. */ + int d_symbol_count; /*!< Counts the number of detected symbols.*/ + int d_symbol_element_count; + /*!< Counts the number of samples in each symbol. */ + bool d_wait_for_NULL; + /*!< Signalizes if we detected the last symbol of an OFDM frame and + * we are now expecting the NULL symbol. */ + bool d_on_triangle; + /*!< Signalizes if we are over the correlation threshold. + * This is used to do a kind of early late synchronization to find + * the correalation peak. + */ + gr_complex d_phase; + bool d_peak_set; + /*!< Signalizes if we already set the peak on the current + * correlation triangle. + */ + float d_correlation_maximum; + /*!< Stores the max correlation value we detected so far on the current + * correlation triangle. + */ + int d_nwritten; + /*!< Stores the number of items, we already wrote to the output buffer.*/ + + /*! \brief Calculates a fixed lag correlation over the given sample sequence. + * + * @param sample Pointer to the first sample of the sequence. + * @param new_calculation If true, calculated the correlation from scratch, else do a moving average. + */ + void delayed_correlation(const gr_complex *sample, bool new_calculation); + + /*! \brief Checks if we reached the maximum of a correlation triangle. + * Peak detection with a very simple, a-causal method. + * @return True, if we found the peak and therefore are at the start of a symbol. + */ + bool detect_start_of_symbol(); + + public: + ofdm_synchronization_cvf_impl(int symbol_length, int cyclic_prefix_length, + int fft_length, int symbols_per_frame); + + ~ofdm_synchronization_cvf_impl(); + + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + + // Where all the action really happens + int general_work(int noutput_items, gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace dab +} // namespace gr + +#endif /* INCLUDED_DAB_OFDM_SYNCHRONIZATION_CVF_IMPL_H */ diff --git a/lib/peak_detector_fb_impl.cc b/lib/peak_detector_fb_impl.cc deleted file mode 100644 index 87455460..00000000 --- a/lib/peak_detector_fb_impl.cc +++ /dev/null @@ -1,121 +0,0 @@ -/* -*- c++ -*- */ -/* This is a version of the GNU Radio peak_detector_fb block before commit 9d9ea63c45b5f314eb344a69340ef49e8edafdfa. - * - * Copyright 2007,2010,2013 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; 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 - -#include -#include "peak_detector_fb_impl.h" -#include - -namespace gr { - namespace dab { - - peak_detector_fb::sptr - peak_detector_fb::make(float threshold_factor_rise, float threshold_factor_fall, int look_ahead, float alpha) - { - return gnuradio::get_initial_sptr - (new peak_detector_fb_impl(threshold_factor_rise, threshold_factor_fall, look_ahead, alpha)); - } - - /* - * The private constructor - */ - peak_detector_fb_impl::peak_detector_fb_impl(float threshold_factor_rise, float threshold_factor_fall, int look_ahead, float alpha) - : gr::sync_block("peak_detector_fb", - gr::io_signature::make(1, 1, sizeof(float)), - gr::io_signature::make(1, 1, sizeof(char))), - d_threshold_factor_rise(threshold_factor_rise), - d_threshold_factor_fall(threshold_factor_fall), - d_look_ahead(look_ahead), d_avg_alpha(alpha), d_avg(0), d_found(0) - {} - - /* - * Our virtual destructor. - */ - peak_detector_fb_impl::~peak_detector_fb_impl() - { - } - - int - peak_detector_fb_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { - float *iptr = (float*)input_items[0]; - char *optr = (char*)output_items[0]; - - memset(optr, 0, noutput_items*sizeof(char)); - - float peak_val = -(float)INFINITY; - int peak_ind = 0; - unsigned char state = 0; - int i = 0; - - //printf("noutput_items %d\n",noutput_items); - while(i < noutput_items) { - if(state == 0) { // below threshold - if(iptr[i] > d_avg*d_threshold_factor_rise) { - state = 1; - } - else { - d_avg = (d_avg_alpha)*iptr[i] + (1-d_avg_alpha)*d_avg; - i++; - } - } - else if(state == 1) { // above threshold, have not found peak - //printf("Entered State 1: %f i: %d noutput_items: %d\n", iptr[i], i, noutput_items); - if(iptr[i] > peak_val) { - peak_val = iptr[i]; - peak_ind = i; - d_avg = (d_avg_alpha)*iptr[i] + (1-d_avg_alpha)*d_avg; - i++; - } - else if(iptr[i] > d_avg*d_threshold_factor_fall) { - d_avg = (d_avg_alpha)*iptr[i] + (1-d_avg_alpha)*d_avg; - i++; - } - else { - optr[peak_ind] = 1; - state = 0; - peak_val = -(float)INFINITY; - //printf("Leaving State 1: Peak: %f Peak Ind: %d i: %d noutput_items: %d\n", - //peak_val, peak_ind, i, noutput_items); - } - } - } - - if(state == 0) { - //printf("Leave in State 0, produced %d\n",noutput_items); - return noutput_items; - } - else { // only return up to passing the threshold - //printf("Leave in State 1, only produced %d of %d\n",peak_ind,noutput_items); - return peak_ind+1; - } - } - - } /* namespace dab */ -} /* namespace gr */ - diff --git a/lib/peak_detector_fb_impl.h b/lib/peak_detector_fb_impl.h deleted file mode 100644 index f0429d96..00000000 --- a/lib/peak_detector_fb_impl.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- c++ -*- */ -/* This is a version of the GNU Radio peak_detector_fb block before commit 9d9ea63c45b5f314eb344a69340ef49e8edafdfa. - * - * Copyright 2007,2010,2013 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DAB_PEAK_DETECTOR_FB_IMPL_H -#define INCLUDED_DAB_PEAK_DETECTOR_FB_IMPL_H - -#include - -namespace gr { - namespace dab { - - class peak_detector_fb_impl : public peak_detector_fb - { - private: - float d_threshold_factor_rise; - float d_threshold_factor_fall; - int d_look_ahead; - float d_avg_alpha; - float d_avg; - unsigned char d_found; - - public: - peak_detector_fb_impl(float threshold_factor_rise, float threshold_factor_fall, int look_ahead, float alpha); - ~peak_detector_fb_impl(); - - void set_threshold_factor_rise(float thr) { d_threshold_factor_rise = thr; } - void set_threshold_factor_fall(float thr) { d_threshold_factor_fall = thr; } - void set_look_ahead(int look) { d_look_ahead = look; } - void set_alpha(float alpha) { d_avg_alpha = alpha; } - float threshold_factor_rise() { return d_threshold_factor_rise; } - float threshold_factor_fall() { return d_threshold_factor_fall; } - int look_ahead() { return d_look_ahead; } - float alpha() { return d_avg_alpha; } - - // Where all the action really happens - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_PEAK_DETECTOR_FB_IMPL_H */ - diff --git a/lib/prune_impl.cc b/lib/prune_impl.cc index 5672ee24..741c4127 100644 --- a/lib/prune_impl.cc +++ b/lib/prune_impl.cc @@ -1,17 +1,18 @@ /* -*- c++ -*- */ -/* +/* * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). - * + * Copyright 2018 Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * * 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, @@ -33,8 +34,8 @@ namespace gr { namespace dab { prune::sptr - prune::make(size_t itemsize, unsigned int length, unsigned int prune_start, unsigned int prune_end) - { + prune::make(size_t itemsize, unsigned int length, unsigned int prune_start, + unsigned int prune_end) { return gnuradio::get_initial_sptr (new prune_impl(itemsize, length, prune_start, prune_end)); } @@ -42,42 +43,47 @@ namespace gr { /* * The private constructor */ - prune_impl::prune_impl(size_t itemsize, unsigned int length, unsigned int prune_start, unsigned int prune_end) + prune_impl::prune_impl(size_t itemsize, unsigned int length, + unsigned int prune_start, unsigned int prune_end) : gr::block("prune", gr::io_signature::make(1, 1, sizeof(char)), gr::io_signature::make(1, 1, sizeof(char))), - d_itemsize(itemsize), d_length(length), d_prune_start(prune_start), d_prune_end(prune_end) - { + d_itemsize(itemsize), d_length(length), + d_prune_start(prune_start), d_prune_end(prune_end) { if (prune_start + prune_end > length) - throw std::out_of_range((boost::format("want to cut %d more items than stream is long") % (prune_start + prune_end - length)).str()); + throw std::out_of_range((boost::format( + "want to cut %d more items than stream is long") % + (prune_start + prune_end - length)).str()); set_output_multiple(length - prune_start - prune_end); - set_relative_rate((length - prune_start - prune_end) / length); + set_relative_rate(static_cast(length - prune_start - prune_end) / static_cast(length)); } /* * Our virtual destructor. */ - prune_impl::~prune_impl() - { + prune_impl::~prune_impl() { } void - prune_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { - ninput_items_required[0] = (noutput_items / (d_length - d_prune_start - d_prune_end)) * d_length; + prune_impl::forecast(int noutput_items, + gr_vector_int &ninput_items_required) { + ninput_items_required[0] = + (noutput_items / (d_length - d_prune_start - d_prune_end)) * + d_length; } int prune_impl::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { const char *in = (const char *) input_items[0]; char *out = (char *) output_items[0]; - for (int i = 0; i < noutput_items / (d_length - d_prune_start - d_prune_end); i++) { - memcpy(out, in + d_prune_start * d_itemsize, (d_length - d_prune_start - d_prune_end) * d_itemsize); + for (int i = 0; + i < noutput_items / (d_length - d_prune_start - d_prune_end); i++) { + memcpy(out, in + d_prune_start * d_itemsize, + (d_length - d_prune_start - d_prune_end) * d_itemsize); in += d_length * d_itemsize; out += (d_length - d_prune_start - d_prune_end) * d_itemsize; } @@ -91,4 +97,3 @@ namespace gr { } /* namespace dab */ } /* namespace gr */ - diff --git a/lib/prune_impl.h b/lib/prune_impl.h index 61879df0..f95afa4f 100644 --- a/lib/prune_impl.h +++ b/lib/prune_impl.h @@ -41,7 +41,8 @@ namespace gr { unsigned int d_prune_end; public: - prune_impl(size_t itemsize, unsigned int length, unsigned int prune_start, unsigned int prune_end); + prune_impl(size_t itemsize, unsigned int length, unsigned int prune_start, + unsigned int prune_end); ~prune_impl(); diff --git a/lib/prune_vectors_impl.cc b/lib/prune_vectors_impl.cc deleted file mode 100644 index 85889957..00000000 --- a/lib/prune_vectors_impl.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "prune_vectors_impl.h" - -namespace gr { - namespace dab { - - prune_vectors::sptr - prune_vectors::make(size_t itemsize, unsigned int length, unsigned int prune_start, unsigned int prune_end) - { - return gnuradio::get_initial_sptr - (new prune_vectors_impl(itemsize, length, prune_start, prune_end)); - } - - prune_vectors_impl::prune_vectors_impl(size_t itemsize, unsigned int length, unsigned int prune_start, - unsigned int prune_end) - : gr::sync_block("prune_vectors", - gr::io_signature::make(1, 1, itemsize * length), - gr::io_signature::make(1, 1, itemsize * (length - prune_start - prune_end))), - d_itemsize(itemsize), d_length(length), d_prune_start(prune_start), d_prune_end(prune_end) - { - if (prune_start + prune_end > length) - fprintf(stderr, "want to prune more than existing"); - } - - - int - prune_vectors_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { - char const *in = (const char *) input_items[0]; - char *out = (char *) output_items[0]; - - for (int i = 0; i < noutput_items; i++) { - memcpy(out, in + d_prune_start * d_itemsize, (d_length - d_prune_start - d_prune_end) * d_itemsize); - in += d_length * d_itemsize; - out += (d_length - d_prune_start - d_prune_end) * d_itemsize; - } - - return noutput_items; - } - - } -} diff --git a/lib/prune_vectors_impl.h b/lib/prune_vectors_impl.h deleted file mode 100644 index cd437e58..00000000 --- a/lib/prune_vectors_impl.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ -#ifndef INCLUDED_DAB_PRUNE_VECTORS_IMPL_H -#define INCLUDED_DAB_PRUNE_VECTORS_IMPL_H - -#include - -namespace gr { - namespace dab { - -class prune_vectors_impl : public prune_vectors -{ - private: - - size_t d_itemsize; - unsigned int d_length; - unsigned int d_prune_start; - unsigned int d_prune_end; - - public: - prune_vectors_impl(size_t itemsize, unsigned int length, unsigned int prune_start, unsigned int prune_end); - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -} -} - -#endif /* INCLUDED_DAB_PRUNE_VECTORS_H */ - diff --git a/lib/puncture_bb_impl.cc b/lib/puncture_bb_impl.cc index a9dca4f6..400de916 100644 --- a/lib/puncture_bb_impl.cc +++ b/lib/puncture_bb_impl.cc @@ -1,17 +1,18 @@ /* -*- c++ -*- */ -/* +/* * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). - * + * Copyright 2018 Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * * 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, @@ -29,14 +30,13 @@ namespace gr { namespace dab { puncture_bb::sptr - puncture_bb::make(const std::vector &puncturing_vector) - { + puncture_bb::make(const std::vector &puncturing_vector) { return gnuradio::get_initial_sptr (new puncture_bb_impl(puncturing_vector)); } - unsigned int puncture_bb_impl::ones(const std::vector &puncturing_vector) - { + unsigned int puncture_bb_impl::ones( + const std::vector &puncturing_vector) { unsigned int onescount = 0; for (unsigned int i = 0; i < puncturing_vector.size(); i++) { if (puncturing_vector[i] == 1) @@ -48,28 +48,27 @@ namespace gr { /* * The private constructor */ - puncture_bb_impl::puncture_bb_impl(const std::vector &puncturing_vector) + puncture_bb_impl::puncture_bb_impl( + const std::vector &puncturing_vector) : gr::block("puncture_bb", gr::io_signature::make(1, 1, sizeof(unsigned char)), gr::io_signature::make(1, 1, sizeof(unsigned char))), - d_puncturing_vector(puncturing_vector) - { + d_puncturing_vector(puncturing_vector) { d_vlen_in = puncturing_vector.size(); d_vlen_out = ones(puncturing_vector); set_output_multiple(d_vlen_out); - set_relative_rate(d_vlen_out / d_vlen_in); + set_relative_rate(static_cast(d_vlen_out) / static_cast(d_vlen_in)); } /* * Our virtual destructor. */ - puncture_bb_impl::~puncture_bb_impl() - { + puncture_bb_impl::~puncture_bb_impl() { } void - puncture_bb_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { + puncture_bb_impl::forecast(int noutput_items, + gr_vector_int &ninput_items_required) { ninput_items_required[0] = noutput_items * d_vlen_in / d_vlen_out; } @@ -77,8 +76,7 @@ namespace gr { puncture_bb_impl::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { const unsigned char *in = (const unsigned char *) input_items[0]; unsigned char *out = (unsigned char *) output_items[0]; @@ -98,4 +96,3 @@ namespace gr { } /* namespace dab */ } /* namespace gr */ - diff --git a/lib/qa_dab.cc b/lib/qa_dab.cc index 4b1ce4d0..c633227a 100644 --- a/lib/qa_dab.cc +++ b/lib/qa_dab.cc @@ -28,8 +28,7 @@ #include "qa_dab.h" CppUnit::TestSuite * -qa_dab::suite() -{ +qa_dab::suite() { CppUnit::TestSuite *s = new CppUnit::TestSuite("dab"); return s; diff --git a/lib/qa_dab.h b/lib/qa_dab.h index 14eec333..140ee250 100644 --- a/lib/qa_dab.h +++ b/lib/qa_dab.h @@ -26,13 +26,13 @@ #include #include -//! collect all the tests for the gr-filter directory +//! collect all the tests for the gr-dab directory class __GR_ATTR_EXPORT qa_dab -{ - public: - //! return suite of tests for all of gr-filter directory - static CppUnit::TestSuite *suite(); -}; + { + public: + //! return suite of tests for all of gr-dab directory + static CppUnit::TestSuite *suite(); + }; #endif /* _QA_DAB_H_ */ diff --git a/lib/qpsk_demapper_vcb_impl.cc b/lib/qpsk_demapper_vcb_impl.cc deleted file mode 100644 index 545f5ffc..00000000 --- a/lib/qpsk_demapper_vcb_impl.cc +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "qpsk_demapper_vcb_impl.h" - -namespace gr { - namespace dab { - -qpsk_demapper_vcb::sptr -qpsk_demapper_vcb::make(int symbol_length) -{ - return gnuradio::get_initial_sptr - (new qpsk_demapper_vcb_impl(symbol_length)); -} - -qpsk_demapper_vcb_impl::qpsk_demapper_vcb_impl(int symbol_length) - : gr::sync_block("qpsk_demapper_vcb", - gr::io_signature::make (1, 1, sizeof(gr_complex)*symbol_length), - gr::io_signature::make (1, 1, sizeof(char)*symbol_length/4)), - d_symbol_length(symbol_length) -{ - assert(symbol_length>0); - assert(symbol_length%4==0); -} - - -int -qpsk_demapper_vcb_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - gr_complex const *in = (const gr_complex *) input_items[0]; - char *out = (char *) output_items[0]; - - char byte = 0; - - for (int i=0; i - -namespace gr { - namespace dab { - -class qpsk_demapper_vcb_impl : public qpsk_demapper_vcb -{ - private: - - int d_symbol_length; - - public: - qpsk_demapper_vcb_impl(int symbol_length); - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; -} -} - -#endif /* INCLUDED_DAB_QPSK_DEMAPPER_VCB_H */ diff --git a/lib/qpsk_mapper_vbc_impl.cc b/lib/qpsk_mapper_vbc_impl.cc deleted file mode 100644 index 9d1a561a..00000000 --- a/lib/qpsk_mapper_vbc_impl.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "qpsk_mapper_vbc_impl.h" - -namespace gr { - namespace dab { - -qpsk_mapper_vbc::sptr -qpsk_mapper_vbc::make(int symbol_length) -{ - return gnuradio::get_initial_sptr - (new qpsk_mapper_vbc_impl(symbol_length)); -} - -qpsk_mapper_vbc_impl::qpsk_mapper_vbc_impl(int symbol_length) - : gr::sync_block("qpsk_mapper_vbc", - gr::io_signature::make (1, 1, sizeof(char)*symbol_length/4), - gr::io_signature::make (1, 1, sizeof(gr_complex)*symbol_length)), - d_symbol_length(symbol_length) -{ - assert(symbol_length>0); - assert(symbol_length%4==0); -} - - -int -qpsk_mapper_vbc_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - char const *in = (const char *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; - - gr_complex symbol; - char byte; - - for (int i=0; i0?-I_SQRT2:I_SQRT2,(byte&64)>0?-I_SQRT2:I_SQRT2); - out[1] = gr_complex((byte&32)>0?-I_SQRT2:I_SQRT2, (byte&16)>0?-I_SQRT2:I_SQRT2); - out[2] = gr_complex((byte&8)>0?-I_SQRT2:I_SQRT2, (byte&4)>0?-I_SQRT2:I_SQRT2); - out[3] = gr_complex((byte&2)>0?-I_SQRT2:I_SQRT2, (byte&1)>0?-I_SQRT2:I_SQRT2); - out+=4; - } - in += d_symbol_length/4; - } - - return noutput_items; -} -} -} diff --git a/lib/qpsk_mapper_vbc_impl.h b/lib/qpsk_mapper_vbc_impl.h deleted file mode 100644 index 64999bc6..00000000 --- a/lib/qpsk_mapper_vbc_impl.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DAB_QPSK_MAPPER_VBC_IMPL_H -#define INCLUDED_DAB_QPSK_MAPPER_VBC_IMPL_H - -#define I_SQRT2 0.707106781187 - -#include - -namespace gr { - namespace dab { - -class qpsk_mapper_vbc_impl : public qpsk_mapper_vbc -{ - private: - int d_symbol_length; - - public: - qpsk_mapper_vbc_impl(int symbol_length); - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -} -} - -#endif /* INCLUDED_DAB_QPSK_MAPPER_VBC_H */ diff --git a/lib/qpsk_mapper_vbvc_impl.cc b/lib/qpsk_mapper_vbvc_impl.cc new file mode 100644 index 00000000..86b4d4f4 --- /dev/null +++ b/lib/qpsk_mapper_vbvc_impl.cc @@ -0,0 +1,80 @@ +/* -*- c++ -*- */ +/* + * Copyright 2017, 2018 by Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * + * 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 + +#include +#include "qpsk_mapper_vbvc_impl.h" + +namespace gr { + namespace dab { + + qpsk_mapper_vbvc::sptr + qpsk_mapper_vbvc::make(unsigned int symbol_length) + { + return gnuradio::get_initial_sptr + (new qpsk_mapper_vbvc_impl(symbol_length)); + } + + /* + * The private constructor + */ + qpsk_mapper_vbvc_impl::qpsk_mapper_vbvc_impl(unsigned int symbol_length) + : gr::sync_block("qpsk_mapper_vbvc", + gr::io_signature::make(1, 1, sizeof(char)*symbol_length/4), + gr::io_signature::make(1, 1, sizeof(gr_complex)*symbol_length)), + d_symbol_length(symbol_length) + {} + + /* + * Our virtual destructor. + */ + qpsk_mapper_vbvc_impl::~qpsk_mapper_vbvc_impl() + { + } + + int + qpsk_mapper_vbvc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const char *in = (const char *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + + for (int i = 0; i < noutput_items; ++i) { + // iterate over each symbol vector + for (int j = 0; j < d_symbol_length/8; ++j) { + // iterate over the symbol vector, but each byte has 8 bit, which are accessed manually + for (int k = 0; k < 8; k++) { + out[i*d_symbol_length + j*8 + k] = + gr_complex((in[i*(d_symbol_length/4) + j]&(0x80>>k))>0?-I_SQRT2:I_SQRT2, + (in[i*(d_symbol_length/4) + d_symbol_length/8 + j]&(0x80>>k))>0?-I_SQRT2:I_SQRT2); + } + } + } + // Tell runtime system how many output items we produced. + return noutput_items; + } + + } /* namespace dab */ +} /* namespace gr */ + diff --git a/lib/qpsk_mapper_vbvc_impl.h b/lib/qpsk_mapper_vbvc_impl.h new file mode 100644 index 00000000..bc0b804a --- /dev/null +++ b/lib/qpsk_mapper_vbvc_impl.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 2017, 2018 by Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * + * 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_DAB_QPSK_MAPPER_VBVC_IMPL_H +#define INCLUDED_DAB_QPSK_MAPPER_VBVC_IMPL_H + +#define I_SQRT2 0.707106781187 + +#include + +namespace gr { + namespace dab { +/*! \brief vector wise working qpsk mapper + * QPSK mapper according to the DAB/DAB+ standard ETSI EN 300 401 + * + * @ingroup packed byte vectors of length symbol_length/4 + * @param symbol_length size of the complex output vectors + */ + class qpsk_mapper_vbvc_impl : public qpsk_mapper_vbvc { + private: + unsigned int d_symbol_length; + + public: + qpsk_mapper_vbvc_impl(unsigned int symbol_length); + + ~qpsk_mapper_vbvc_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); + }; + + } // namespace dab +} // namespace gr + +#endif /* INCLUDED_DAB_QPSK_MAPPER_VBVC_IMPL_H */ + diff --git a/lib/reed_solomon_decode_bb_impl.cc b/lib/reed_solomon_decode_bb_impl.cc index bb84ac34..96c60c5a 100644 --- a/lib/reed_solomon_decode_bb_impl.cc +++ b/lib/reed_solomon_decode_bb_impl.cc @@ -41,8 +41,7 @@ namespace gr { namespace dab { reed_solomon_decode_bb::sptr - reed_solomon_decode_bb::make(int bit_rate_n) - { + reed_solomon_decode_bb::make(int bit_rate_n) { return gnuradio::get_initial_sptr (new reed_solomon_decode_bb_impl(bit_rate_n)); } @@ -54,8 +53,7 @@ namespace gr { : gr::block("reed_solomon_decode_bb", gr::io_signature::make(1, 1, sizeof(unsigned char)), gr::io_signature::make(1, 1, sizeof(unsigned char))), - d_bit_rate_n(bit_rate_n) - { + d_bit_rate_n(bit_rate_n) { rs_handle = init_rs_char(8, 0x11D, 0, 1, 10, 135); if (!rs_handle) { GR_LOG_DEBUG(d_logger, "RS init failed"); @@ -71,13 +69,12 @@ namespace gr { /* * Our virtual destructor. */ - reed_solomon_decode_bb_impl::~reed_solomon_decode_bb_impl() - { + reed_solomon_decode_bb_impl::~reed_solomon_decode_bb_impl() { free_rs_char(rs_handle); } - void reed_solomon_decode_bb_impl::DecodeSuperframe(uint8_t *sf, size_t sf_len) - { + void + reed_solomon_decode_bb_impl::DecodeSuperframe(uint8_t *sf, size_t sf_len) { // // insert errors for test // sf[0] ^= 0xFF; // sf[10] ^= 0xFF; @@ -109,23 +106,21 @@ namespace gr { sf[pos * subch_index + i] = rs_packet[pos]; } } - GR_LOG_DEBUG(d_logger, format("RS corrected %d errors in superframe") % total_corr_count); d_corrected_errors = total_corr_count; } void - reed_solomon_decode_bb_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { - ninput_items_required[0] = noutput_items*120/110; + reed_solomon_decode_bb_impl::forecast(int noutput_items, + gr_vector_int &ninput_items_required) { + ninput_items_required[0] = noutput_items * 120 / 110; } int reed_solomon_decode_bb_impl::general_work(int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { const unsigned char *in = (const unsigned char *) input_items[0]; unsigned char *out = (unsigned char *) output_items[0]; diff --git a/lib/reed_solomon_decode_bb_impl.h b/lib/reed_solomon_decode_bb_impl.h index 0dcf011c..6a05e13d 100644 --- a/lib/reed_solomon_decode_bb_impl.h +++ b/lib/reed_solomon_decode_bb_impl.h @@ -45,12 +45,12 @@ namespace gr { class reed_solomon_decode_bb_impl : public reed_solomon_decode_bb { private: int d_bit_rate_n; - int d_superframe_size; - int d_superframe_size_rs; + int d_superframe_size; /*!< size of a superframe in byte with rs code words*/ + int d_superframe_size_rs; /*!< size of a superframe in byte without rs code words*/ void *rs_handle; - uint8_t rs_packet[120]; - int corr_pos[10]; - int d_corrected_errors; + uint8_t rs_packet[120]; /*!< buffer for rs algorithm*/ + int corr_pos[10]; /*!< positions of detected and correctable errors*/ + int d_corrected_errors; /*!< number of corrected errors in the current superframe*/ void DecodeSuperframe(uint8_t *sf, size_t sf_len); @@ -59,8 +59,7 @@ namespace gr { ~reed_solomon_decode_bb_impl(); - virtual int get_corrected_errors() - { return d_corrected_errors; } + virtual int get_corrected_errors() { return d_corrected_errors; } // Where all the action really happens void forecast(int noutput_items, gr_vector_int &ninput_items_required); diff --git a/lib/reed_solomon_encode_bb_impl.cc b/lib/reed_solomon_encode_bb_impl.cc index 7ed96050..ff9f2f60 100644 --- a/lib/reed_solomon_encode_bb_impl.cc +++ b/lib/reed_solomon_encode_bb_impl.cc @@ -41,21 +41,19 @@ namespace gr { namespace dab { reed_solomon_encode_bb::sptr - reed_solomon_encode_bb::make(int bit_rate_n) - { + reed_solomon_encode_bb::make(int bit_rate_n) { return gnuradio::get_initial_sptr - (new reed_solomon_encode_bb_impl(bit_rate_n)); + (new reed_solomon_encode_bb_impl(bit_rate_n)); } /* * The private constructor */ reed_solomon_encode_bb_impl::reed_solomon_encode_bb_impl(int bit_rate_n) - : gr::block("reed_solomon_encode_bb", - gr::io_signature::make(1, 1, sizeof(unsigned char)), - gr::io_signature::make(1, 1, sizeof(unsigned char))), - d_bit_rate_n(bit_rate_n) - { + : gr::block("reed_solomon_encode_bb", + gr::io_signature::make(1, 1, sizeof(unsigned char)), + gr::io_signature::make(1, 1, sizeof(unsigned char))), + d_bit_rate_n(bit_rate_n) { //initialize Reed Solomon rs_handle = init_rs_char(8, 0x11D, 0, 1, 10, 135); if (!rs_handle) { @@ -71,50 +69,49 @@ namespace gr { /* * Our virtual destructor. */ - reed_solomon_encode_bb_impl::~reed_solomon_encode_bb_impl() - { + reed_solomon_encode_bb_impl::~reed_solomon_encode_bb_impl() { free_rs_char(rs_handle); } void - reed_solomon_encode_bb_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) - { - ninput_items_required[0] = noutput_items*110/120; + reed_solomon_encode_bb_impl::forecast(int noutput_items, + gr_vector_int &ninput_items_required) { + ninput_items_required[0] = noutput_items * 110 / 120; } int - reed_solomon_encode_bb_impl::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + reed_solomon_encode_bb_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { const unsigned char *in = (const unsigned char *) input_items[0]; unsigned char *out = (unsigned char *) output_items[0]; unsigned char rs_in[110]; unsigned char rs_parity[10]; - for(int n=0; n < noutput_items/d_superframe_size_rs; n++){ + for (int n = 0; n < noutput_items / d_superframe_size_rs; n++) { // virtual interleaving: a d_bit_rate_n x 110 block is now read row wise instead of column wise for (int row = 0; row < d_bit_rate_n; row++) { // write scrambled in_vector for RS for (int i = 0; i < 110; ++i) { - rs_in[i] = in[n * d_superframe_size_in + d_bit_rate_n*i + row]; + rs_in[i] = in[n * d_superframe_size_in + d_bit_rate_n * i + row]; } // calculate parity bytes encode_rs_char(rs_handle, rs_in, rs_parity); // write to output buffer for (int i = 0; i < 110; ++i) { - out[n*d_superframe_size_rs + d_bit_rate_n*i + row] = rs_in[i]; + out[n * d_superframe_size_rs + d_bit_rate_n * i + row] = rs_in[i]; } for (int i = 110; i < 120; ++i) { - out[n*d_superframe_size_rs + d_bit_rate_n*i + row] = rs_parity[i-110]; + out[n * d_superframe_size_rs + d_bit_rate_n * i + row] = rs_parity[ + i - 110]; } } } // Tell runtime system how many input items we consumed on // each input stream. - consume_each (noutput_items*110/120); + consume_each(noutput_items * 110 / 120); // Tell runtime system how many output items we produced. return noutput_items; diff --git a/lib/reed_solomon_encode_bb_impl.h b/lib/reed_solomon_encode_bb_impl.h index 5afb8eb4..489d3a8a 100644 --- a/lib/reed_solomon_encode_bb_impl.h +++ b/lib/reed_solomon_encode_bb_impl.h @@ -35,30 +35,34 @@ extern "C" { namespace gr { namespace dab { -/*! \brief Reed Solomon encoder for DAB+ transmission - * Reed Solomon RS(120, 110, t=5) with virtual interleaving; derived from RS(255, 245, t=5). Details see ETSI TS 102 563 clause 6.0 and 6.1. - * @param bit_rate_n data rate in multiples of 8kbit/s +/*! \brief Reed Solomon encoder for DAB+ transmission. + * Reed Solomon RS(120, 110, t=5) with virtual interleaving. + * Derived from RS(255, 245, t=5). Details see ETSI TS 102 563 clause 6.0 and 6.1. + * @param bit_rate_n Data rate in multiples of 8kbit/s. */ - class reed_solomon_encode_bb_impl : public reed_solomon_encode_bb - { - private: + class reed_solomon_encode_bb_impl : public reed_solomon_encode_bb { + + private: int d_bit_rate_n; int d_superframe_size_rs; + /*!< size of a superframe in byte with appended rs code words*/ int d_superframe_size_in; + /*!< size of a superframe in byte without rs code words*/ void *rs_handle; - public: + public: reed_solomon_encode_bb_impl(int bit_rate_n); + ~reed_solomon_encode_bb_impl(); // Where all the action really happens - void forecast (int noutput_items, gr_vector_int &ninput_items_required); + void forecast(int noutput_items, gr_vector_int &ninput_items_required); int general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; } // namespace dab diff --git a/lib/repartition_vectors_impl.cc b/lib/repartition_vectors_impl.cc deleted file mode 100644 index 50eb70a5..00000000 --- a/lib/repartition_vectors_impl.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "repartition_vectors_impl.h" - -namespace gr { - namespace dab { - -repartition_vectors::sptr -repartition_vectors::make(size_t itemsize, unsigned int vlen_in, unsigned int vlen_out, unsigned int multiply, unsigned int divide) -{ - return gnuradio::get_initial_sptr - (new repartition_vectors_impl(itemsize, vlen_in, vlen_out, multiply, divide)); -} - -repartition_vectors_impl::repartition_vectors_impl(size_t itemsize, unsigned int vlen_in, unsigned int vlen_out, unsigned int multiply, unsigned int divide) - : gr::block("repartition_vectors", - gr::io_signature::make2 (2, 2, itemsize*vlen_in, sizeof(char)), - gr::io_signature::make2 (2, 2, itemsize*vlen_out, sizeof(char))), - d_itemsize(itemsize), d_vlen_in(vlen_in), d_vlen_out(vlen_out), d_multiply(multiply), d_divide(divide), d_synced(0) -{ - assert(vlen_in * multiply == vlen_out * divide); - set_output_multiple(divide); -} - -void -repartition_vectors_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) -{ - int in_req = noutput_items / d_divide * d_multiply; - - unsigned ninputs = ninput_items_required.size (); - for (unsigned i = 0; i < ninputs; i++) - ninput_items_required[i] = in_req; -} - -int -repartition_vectors_impl::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const char *iptr = (const char *) input_items[0]; - const char *trigger = (const char *) input_items[1]; - - char *optr = (char *) output_items[0]; - char *triggerout = (char *) output_items[1]; - - int n_consumed = 0; - int n_produced = 0; - - while (d_synced==0 && ninput_items[0]>n_consumed && ninput_items[1]>n_consumed) { - if (*trigger == 1) { - d_synced=1; - } else { - n_consumed++; - iptr += d_vlen_in*d_itemsize; - trigger++; - } - } - - while (n_consumed + (int)d_multiply <= ninput_items[0] && n_consumed + (int)d_multiply <= ninput_items[1] && n_produced + (int)d_divide <= noutput_items) { - - /* complete new block or is there already a next trigger? */ - for (unsigned int i=1; i - -namespace gr { - namespace dab { -/*! \brief reorder vectors to new vector size in order to organize - * - * input1: vector stream with vector length vlen_in - * input2: trigger stream - * - * output1: vector streasm with vector length vlen_out - * output2: trigger stream - * - * @param itemsize sizeof input and outputstream of port 0 - * @param vlen_in vector length of inputstream - * @param vlen_out vector length of outputstream (repartitioned) - * @param multiply number of input items which form one logical unit - * @param divide number of input elements of size vlen_out which are passed through - * - */ - -class repartition_vectors_impl : public repartition_vectors -{ - private: - - size_t d_itemsize; - unsigned int d_vlen_in; - unsigned int d_vlen_out; - unsigned int d_multiply; - unsigned int d_divide; - unsigned int d_synced; - - public: - repartition_vectors_impl(size_t itemsize, unsigned int vlen_in, unsigned int vlen_out, unsigned int multiply, unsigned int divide); - void forecast (int noutput_items, gr_vector_int &ninput_items_required); - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -} -} - -#endif /* INCLUDED_DAB_BLOCK_PARTITIONING_VBB_H */ diff --git a/lib/select_cus_vfvf_impl.cc b/lib/select_cus_vfvf_impl.cc new file mode 100644 index 00000000..1aa47046 --- /dev/null +++ b/lib/select_cus_vfvf_impl.cc @@ -0,0 +1,94 @@ +/* -*- c++ -*- */ +/* + * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). + * + * 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 + +#include +#include "select_cus_vfvf_impl.h" + +namespace gr { + namespace dab { + + select_cus_vfvf::sptr + select_cus_vfvf::make(unsigned int vlen, unsigned int frame_len, + unsigned int address, unsigned int size) { + return gnuradio::get_initial_sptr(new select_cus_vfvf_impl(vlen, + frame_len, + address, + size)); + } + + /* + * The private constructor + */ + select_cus_vfvf_impl::select_cus_vfvf_impl(unsigned int vlen, + unsigned int frame_len, + unsigned int address, + unsigned int size) + : gr::block("select_cus_vfvf", + gr::io_signature::make(1, 1, vlen * sizeof(float)), + gr::io_signature::make(1, 1, vlen * sizeof(float))), + d_vlen(vlen), + d_frame_len(frame_len), + d_address(address), + d_size(size) { + } + + /* + * Our virtual destructor. + */ + select_cus_vfvf_impl::~select_cus_vfvf_impl() { + } + + void + select_cus_vfvf_impl::forecast(int noutput_items, + gr_vector_int &ninput_items_required) { + ninput_items_required[0] = noutput_items; + } + + int + select_cus_vfvf_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + const float *in = (const float *) input_items[0]; + float *out = (float *) output_items[0]; + unsigned int nwritten = 0; + + for (int i = 0; i < noutput_items; ++i) { + if (d_address <= (nitems_read(0) + i) % d_frame_len && + (nitems_read(0) + i) % d_frame_len < d_address + d_size) { + //this cu is one of the selected subchannel -> copy it to ouput buffer + memcpy(&out[nwritten++ * d_vlen], &in[i * d_vlen], d_vlen * sizeof(float)); + } + } + // Tell runtime system how many input items we consumed on + // each input stream. + consume_each(noutput_items); + + // Tell runtime system how many output items we produced. + return nwritten; + } + + } /* namespace dab */ +} /* namespace gr */ + diff --git a/lib/unpuncture_ff_impl.h b/lib/select_cus_vfvf_impl.h similarity index 56% rename from lib/unpuncture_ff_impl.h rename to lib/select_cus_vfvf_impl.h index d8bb4bf2..df22c133 100644 --- a/lib/unpuncture_ff_impl.h +++ b/lib/select_cus_vfvf_impl.h @@ -18,34 +18,36 @@ * Boston, MA 02110-1301, USA. */ -#ifndef INCLUDED_DAB_UNPUNCTURE_FF_IMPL_H -#define INCLUDED_DAB_UNPUNCTURE_FF_IMPL_H +#ifndef INCLUDED_DAB_SELECT_CUS_VFVF_IMPL_H +#define INCLUDED_DAB_SELECT_CUS_VFVF_IMPL_H -#include +#include namespace gr { namespace dab { -/*! \brief unpuncturing of a stream sequence - * - * unpuncturing of a stream sequence according to the puncturing_vector (writing a stream element at a '1' and writing the fillval at a '0') - * - * @param puncturing_vector vector with puncturing sequence, length of puncturing_vector is length of a stream sequence - * @param fillval value to fill in for a zero of the puncturing vector +/*! \brief Selects items out of a stream, defined by start address and size. + * This block is used to select the data of one MSC sub-channel + * out of a transmission frame. * + * @param vlen Vector size of input and output vectors, + * defining the item size on witch the address and size variables base on. + * @param frame_length Length in items of a frame. + * (each item is a vector with size vlen) + * @param address Number of the first item in each frame to be copied. + * @param size Number of items to copy in each frame. */ - class unpuncture_ff_impl : public unpuncture_ff { + class select_cus_vfvf_impl : public select_cus_vfvf { private: - unsigned int ones(const std::vector &puncturing_vector); - - std::vector d_puncturing_vector; - float d_fillval; - unsigned int d_vlen_in; - unsigned int d_vlen_out; + unsigned int d_vlen; + unsigned int d_frame_len; + unsigned int d_address; + unsigned int d_size; public: - unpuncture_ff_impl(const std::vector &puncturing_vector, float fillval); + select_cus_vfvf_impl(unsigned int vlen, unsigned int frame_len, + unsigned int address, unsigned int size); - ~unpuncture_ff_impl(); + ~select_cus_vfvf_impl(); // Where all the action really happens void forecast(int noutput_items, gr_vector_int &ninput_items_required); @@ -59,5 +61,5 @@ namespace gr { } // namespace dab } // namespace gr -#endif /* INCLUDED_DAB_UNPUNCTURE_FF_IMPL_H */ +#endif /* INCLUDED_DAB_SELECT_CUS_VFVF_IMPL_H */ diff --git a/lib/select_subch_vfvf_impl.cc b/lib/select_subch_vfvf_impl.cc deleted file mode 100644 index 61a8ce51..00000000 --- a/lib/select_subch_vfvf_impl.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). - * - * 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 - -#include -#include "select_subch_vfvf_impl.h" - -namespace gr { - namespace dab { - - select_subch_vfvf::sptr - select_subch_vfvf::make(unsigned int vlen_in, unsigned int vlen_out, unsigned int address, - unsigned int total_size) - { - return gnuradio::get_initial_sptr - (new select_subch_vfvf_impl(vlen_in, vlen_out, address, total_size)); - } - - /* - * The private constructor - */ - select_subch_vfvf_impl::select_subch_vfvf_impl(unsigned int vlen_in, unsigned int vlen_out, - unsigned int address, unsigned int total_size) - : gr::block("select_subch_vfvf", - gr::io_signature::make(1, 1, sizeof(float) * vlen_in), - gr::io_signature::make(1, 1, sizeof(float) * vlen_out)), - d_vlen_in(vlen_in), d_vlen_out(vlen_out), d_address(address), d_total_size(total_size) - { - //sanity check - if (vlen_out % vlen_in != 0) - throw std::invalid_argument("vlen_out no multiple of vlen_in"); - if (address * vlen_in + vlen_out > total_size * vlen_in) - throw std::out_of_range("vlen_out too long or address wrong"); - - set_relative_rate(1 / total_size); - } - - /* - * Our virtual destructor. - */ - select_subch_vfvf_impl::~select_subch_vfvf_impl() - { - } - - void - select_subch_vfvf_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { - ninput_items_required[0] = noutput_items * d_total_size; - } - - int - select_subch_vfvf_impl::general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { - const float *in = (const float *) input_items[0]; - float *out = (float *) output_items[0]; - - for (int i = 0; i < noutput_items; i++) { - memcpy(&out[i * d_vlen_out], &in[d_vlen_in * (i * d_total_size + d_address)], - d_vlen_out * sizeof(float)); - } - // Tell runtime system how many input items we consumed on - // each input stream. - consume_each(noutput_items * d_total_size); - - // Tell runtime system how many output items we produced. - return noutput_items; - } - - } /* namespace dab */ -} /* namespace gr */ - diff --git a/lib/select_subch_vfvf_impl.h b/lib/select_subch_vfvf_impl.h deleted file mode 100644 index cb46e3ce..00000000 --- a/lib/select_subch_vfvf_impl.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). - * - * 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_DAB_SELECT_SUBCH_VFVF_IMPL_H -#define INCLUDED_DAB_SELECT_SUBCH_VFVF_IMPL_H - -#include - -namespace gr { - namespace dab { -/*! \brief selects vectors out of input vectors that belong to one subchannel - * - * input: float vector of size vlen_in - * - * output: float vector of size vlen_out - * - * selects vlen_out/vlen_in vectors of total_size input vectors, beginning at address - * - * @param vlen_in Length of input vector in floats. - * @param vlen_out Length of output vector in floats. - * @param address number of input vector where output the output vector begins - * @param total_size size in input vectors of one frame (dumped after output vector is selected) - */ - class select_subch_vfvf_impl : public select_subch_vfvf - { - private: - unsigned int d_vlen_in, d_vlen_out, d_address, d_total_size; - - public: - select_subch_vfvf_impl(unsigned int vlen_in, unsigned int vlen_out, unsigned int address, unsigned int total_size); - ~select_subch_vfvf_impl(); - - // Where all the action really happens - void forecast (int noutput_items, gr_vector_int &ninput_items_required); - - int general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - }; - - } // namespace dab -} // namespace gr - -#endif /* INCLUDED_DAB_SELECT_SUBCH_VFVF_IMPL_H */ - diff --git a/lib/select_vectors_impl.cc b/lib/select_vectors_impl.cc deleted file mode 100644 index 6eb79672..00000000 --- a/lib/select_vectors_impl.cc +++ /dev/null @@ -1,113 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -/* - * config.h is generated by configure. It contains the results - * of probing for features, options etc. It should be the first - * file included in your .cc file. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "select_vectors_impl.h" - -namespace gr { - namespace dab { - -select_vectors::sptr -select_vectors::make(size_t itemsize, unsigned int length, unsigned int num_select, unsigned int num_skip) -{ - return gnuradio::get_initial_sptr - (new select_vectors_impl(itemsize, length, num_select, num_skip)); -} - -select_vectors_impl::select_vectors_impl(size_t itemsize, unsigned int length, unsigned int num_select, unsigned int num_skip) - : gr::block("select_vectors", - gr::io_signature::make2 (2, 2, itemsize*length, sizeof(char)), - gr::io_signature::make2 (2, 2, itemsize*length, sizeof(char))), - d_itemsize(itemsize), d_length(length), d_num_select(num_select), d_num_skip(num_skip), d_index(num_select+num_skip) /* <- dont output anything before 1st trigger */ -{ - assert(d_num_select!=0); - assert(d_length!=0); -} - -void -select_vectors_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) -{ - int in_req = noutput_items * (d_num_skip+d_num_select)/d_num_select; /* very coarse .. */ - - unsigned ninputs = ninput_items_required.size (); - for (unsigned i = 0; i < ninputs; i++) - ninput_items_required[i] = in_req; -} - -int -select_vectors_impl::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const char *iptr = (const char *) input_items[0]; - const char *trigger = (const char *) input_items[1]; - - char *optr = (char *) output_items[0]; - char *triggerout = (char *) output_items[1]; - - int n_consumed = 0; - int n_produced = 0; - - - while (n_consumed < ninput_items[0] && n_consumed < ninput_items[1] && n_produced < noutput_items) { - - /* start of frame? */ - if (*trigger++ == 1) - d_index=0; - - /* select this vector? */ - if (d_index >= d_num_skip && d_index < d_num_select + d_num_skip) { - /* trigger signal */ - if (d_index == d_num_skip) - *triggerout++ = 1; - else - *triggerout++ = 0; - /* data */ - memcpy(optr, iptr, d_length*d_itemsize); - iptr += d_length*d_itemsize; - optr += d_length*d_itemsize; - n_produced++; - } else { - iptr += d_length*d_itemsize; - } - - d_index++; - n_consumed++; - } - - consume_each(n_consumed); - return n_produced; -} - -} -} - diff --git a/lib/select_vectors_impl.h b/lib/select_vectors_impl.h deleted file mode 100644 index f5e662db..00000000 --- a/lib/select_vectors_impl.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ -#ifndef INCLUDED_DAB_SELECT_VECTORS_IMPL_H -#define INCLUDED_DAB_SELECT_VECTORS_IMPL_H - -#include - -namespace gr { - namespace dab { - -/*! \brief select a row of vectors - * - * input1: vector of size length*itemsize - * input2: char stream with triggers for start of transmission frame - * - * output1: vector of size length*itemsize - * output2: same as input2 - * - * selects a row of vectors of the transmission frame; start of a transmission frame is triggerd by input2 - * - * @param itemsize sizeof input and outputstream of port 0 - * @param length vector length - * @param num_select number of vectors to select - * @param num_skip number of vectors to skip before selection of num_select vectors - * - */ - class select_vectors_impl : public select_vectors { - private: - size_t d_itemsize; - unsigned int d_length; - unsigned int d_num_select; - unsigned int d_num_skip; - unsigned int d_index; - - public: - select_vectors_impl(size_t itemsize, unsigned int length, unsigned int num_select, unsigned int num_skip); - - void forecast(int noutput_items, gr_vector_int &ninput_items_required); - - int general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - }; - - } -} - -#endif /* INCLUDED_DAB_SELECT_VECTORS_H */ diff --git a/lib/sum_phasor_trig_vcc_impl.cc b/lib/sum_phasor_trig_vcc_impl.cc index bff21dba..79533626 100644 --- a/lib/sum_phasor_trig_vcc_impl.cc +++ b/lib/sum_phasor_trig_vcc_impl.cc @@ -37,67 +37,63 @@ namespace gr { namespace dab { -sum_phasor_trig_vcc::sptr -sum_phasor_trig_vcc::make(unsigned int length) -{ - return gnuradio::get_initial_sptr - (new sum_phasor_trig_vcc_impl(length)); -} + sum_phasor_trig_vcc::sptr + sum_phasor_trig_vcc::make(unsigned int length) { + return gnuradio::get_initial_sptr + (new sum_phasor_trig_vcc_impl(length)); + } -sum_phasor_trig_vcc_impl::sum_phasor_trig_vcc_impl(unsigned int length) - : gr::sync_block("sum_phasor_trig_vcc", - gr::io_signature::make2 (2, 2, sizeof(gr_complex)*length, sizeof(char)), - gr::io_signature::make2 (2, 2, sizeof(gr_complex)*length, sizeof(char))), - d_length(length), d_last_symbol(length,0) -{ -} + sum_phasor_trig_vcc_impl::sum_phasor_trig_vcc_impl(unsigned int length) + : gr::sync_block("sum_phasor_trig_vcc", + gr::io_signature::make2(2, 2, sizeof(gr_complex) * length, sizeof(char)), + gr::io_signature::make2(2, 2, sizeof(gr_complex) * length, sizeof(char))), + d_length(length), + d_last_symbol(length, 0) { + } -int -sum_phasor_trig_vcc_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - gr_complex const *in = (const gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; - gr_complex *lastout; - const char *frame_start = (const char *) input_items[1]; - char *o_frame_start = (char *) output_items[1]; - - for(int i = 0; i < noutput_items; i++){ - if (*frame_start==1) { - for (unsigned int j=0; j d_last_symbol; + unsigned int d_length; + std::vector d_last_symbol; - public: - sum_phasor_trig_vcc_impl(unsigned int length); - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; + public: + sum_phasor_trig_vcc_impl(unsigned int length); -} + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } } #endif /* INCLUDED_DAB_SUM_PHASOR_TRIG_VCC_H */ diff --git a/lib/test_dab.cc b/lib/test_dab.cc index 1b8f46e3..3b642b6d 100644 --- a/lib/test_dab.cc +++ b/lib/test_dab.cc @@ -33,8 +33,7 @@ #include int -main (int argc, char **argv) -{ +main(int argc, char **argv) { CppUnit::TextTestRunner runner; std::ofstream xmlfile(get_unittest_path("dab.xml").c_str()); CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile); diff --git a/lib/time_deinterleave_ff_impl.cc b/lib/time_deinterleave_ff_impl.cc index 72279225..cda45d85 100644 --- a/lib/time_deinterleave_ff_impl.cc +++ b/lib/time_deinterleave_ff_impl.cc @@ -28,10 +28,10 @@ namespace gr { namespace dab { time_deinterleave_ff::sptr - time_deinterleave_ff::make(int vector_length, const std::vector &scrambling_vector) - { - return gnuradio::get_initial_sptr - (new time_deinterleave_ff_impl(vector_length, scrambling_vector)); + time_deinterleave_ff::make(int vector_length, + const std::vector &scrambling_vector) { + return gnuradio::get_initial_sptr(new time_deinterleave_ff_impl(vector_length, + scrambling_vector)); } /* @@ -42,33 +42,32 @@ namespace gr { : gr::sync_block("time_deinterleave_ff", gr::io_signature::make(1, 1, sizeof(float)), gr::io_signature::make(1, 1, sizeof(float))), - d_vector_length(vector_length), d_scrambling_vector(scrambling_vector) - { + d_vector_length(vector_length), + d_scrambling_vector(scrambling_vector) { d_scrambling_length = scrambling_vector.size(); // size of the scrambling vector set_output_multiple(d_vector_length); - set_history((d_scrambling_length-1)*d_vector_length + 1); //need for max delay of (scrambling_length-1) * 24ms + // set history (need for max delay of (scrambling_length-1) * 24ms) + set_history((d_scrambling_length - 1) * d_vector_length + 1); } /* * Our virtual destructor. */ - time_deinterleave_ff_impl::~time_deinterleave_ff_impl() - { + time_deinterleave_ff_impl::~time_deinterleave_ff_impl() { } int time_deinterleave_ff_impl::work(int noutput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { const float *in = (const float *) input_items[0]; float *out = (float *) output_items[0]; - for (int i = 0; i < noutput_items/d_vector_length; i++) { + for (int i = 0; i < noutput_items / d_vector_length; i++) { // produce output vectors for (int j = 0; j < d_vector_length; j++) { - *out++ = in[d_vector_length * (i + (d_scrambling_length - 1) - ((d_scrambling_length - 1) - d_scrambling_vector[j % d_scrambling_length])) + j]; - //*out++ = in[i*d_vector_length + d_scrambling_vector[j%d_scrambling_length]*d_vector_length + j - (j%d_scrambling_length) + d_scrambling_vector[j%d_scrambling_length]]; + *out++ = in[d_vector_length * (i + (d_scrambling_length - 1) - ((d_scrambling_length - 1) - + d_scrambling_vector[j % d_scrambling_length])) + j]; } } // Tell runtime system how many output items we produced. diff --git a/lib/time_deinterleave_ff_impl.h b/lib/time_deinterleave_ff_impl.h index 0f0171a3..60e3e265 100644 --- a/lib/time_deinterleave_ff_impl.h +++ b/lib/time_deinterleave_ff_impl.h @@ -24,35 +24,40 @@ #include namespace gr { - namespace dab { -/*! \brief applies time deinterleaving to a vector (convolutional deinterleaving -> descrambling and delay) + namespace dab { +/*! \brief Applies time deinterleaving to a vector + * convolutional deinterleaving -> descrambling and delay * - * applies convolutional deinterleaving to a vector with its max[vector_length] followers, the scrambling_vector describes which vector element comes from which follower - * delays the elements of a max delay of d_scrambling_length-1 - * more information to the interleaving rules on ETSI EN 300 401 chapter 12 - * this deinterleaver restores a bitstream interleaved by the block time_interleave_bb + * Applies convolutional deinterleaving to a vector with its max[vector_length] followers, + * the scrambling_vector describes which vector element comes from which follower. + * Delays the elements of a max delay of d_scrambling_length-1. + * More information to the interleaving rules on ETSI EN 300 401 chapter 12. + * This deinterleaver restores a bitstream interleaved by the block time_interleave_bb. * - * @param vector_length length of input vectors - * @param scrambling_vector vector with scrambling parameters (see DAB standard p.138) + * @param vector_length Length of the input vectors. + * @param scrambling_vector Vector with scrambling parameters. + * (see ETSI EN 300 401 chapter 12) * */ - class time_deinterleave_ff_impl : public time_deinterleave_ff - { - private: - int d_scrambling_length, d_vector_length; - std::vector d_scrambling_vector; - - public: - time_deinterleave_ff_impl(int vector_length, const std::vector &scrambling_vector); - ~time_deinterleave_ff_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); - }; - - } // namespace dab + class time_deinterleave_ff_impl : public time_deinterleave_ff { + + private: + int d_scrambling_length, d_vector_length; + std::vector d_scrambling_vector; + + public: + time_deinterleave_ff_impl(int vector_length, + const std::vector &scrambling_vector); + + ~time_deinterleave_ff_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); + }; + + } // namespace dab } // namespace gr #endif /* INCLUDED_DAB_TIME_DEINTERLEAVE_FF_IMPL_H */ diff --git a/lib/time_interleave_bb_impl.cc b/lib/time_interleave_bb_impl.cc index 8cbc33c7..277c24c9 100644 --- a/lib/time_interleave_bb_impl.cc +++ b/lib/time_interleave_bb_impl.cc @@ -29,10 +29,10 @@ namespace gr { namespace dab { time_interleave_bb::sptr - time_interleave_bb::make(int vector_length, const std::vector &scrambling_vector) - { - return gnuradio::get_initial_sptr - (new time_interleave_bb_impl(vector_length, scrambling_vector)); + time_interleave_bb::make(int vector_length, + const std::vector &scrambling_vector) { + return gnuradio::get_initial_sptr(new time_interleave_bb_impl(vector_length, + scrambling_vector)); } /* @@ -43,33 +43,31 @@ namespace gr { : gr::sync_block("time_interleave_bb", gr::io_signature::make(1, 1, sizeof(unsigned char) * vector_length), gr::io_signature::make(1, 1, sizeof(unsigned char) * vector_length)), - d_vector_length(vector_length), d_scrambling_vector(scrambling_vector) - { + d_vector_length(vector_length), + d_scrambling_vector(scrambling_vector) { d_scrambling_length = scrambling_vector.size(); //size of the scrambling vector - set_history(d_scrambling_length); //need for max delay of (scrambling_length-1) * 24ms + set_history( + d_scrambling_length); //need for max delay of (scrambling_length-1) * 24ms } /* * Our virtual destructor. */ - time_interleave_bb_impl::~time_interleave_bb_impl() - { + time_interleave_bb_impl::~time_interleave_bb_impl() { } int time_interleave_bb_impl::work(int noutput_items, gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + gr_vector_void_star &output_items) { const unsigned char *in = (const unsigned char *) input_items[0]; unsigned char *out = (unsigned char *) output_items[0]; // produce output vectors for (int i = 0; i < noutput_items; i++) { //iteration over produced output vectors for (int j = 0; j < d_vector_length; j++) { //iteration over elements of vector - //*out++ = in[vec_length * (i + (scrambling_length-1) - d_scrambling_vector[j % scrambling_length]) + j]; - *out++ = in[d_vector_length * (i + (d_scrambling_length - 1) - d_scrambling_vector[j % d_scrambling_length]) + - j]; + *out++ = in[d_vector_length * (i + (d_scrambling_length - 1) - + d_scrambling_vector[j % d_scrambling_length]) + j]; } } diff --git a/lib/time_interleave_bb_impl.h b/lib/time_interleave_bb_impl.h index 330abdb0..d7dd5b27 100644 --- a/lib/time_interleave_bb_impl.h +++ b/lib/time_interleave_bb_impl.h @@ -24,35 +24,37 @@ #include namespace gr { - namespace dab { -/*! \brief applies time interleaving to a vector (convolutional interleaving -> scrambling and delay) + namespace dab { +/*! \brief Applies time interleaving to a vector + * convolutional interleaving -> scrambling and delay * - * applies convolutional interleaving to a vector with its max[vector_length] followers, the scrambling_vector describes which vector element comes from which follower - * delays the elements of a max delay of d_scrambling_length-1 - * more information to the interleaving rules on ETSI EN 300 401 chapter 12 + * Applies convolutional interleaving to a vector with its max[vector_length] followers, + * the scrambling_vector describes which vector element comes from which follower. + * Delays the elements of a max delay of d_scrambling_length-1. + * More information to the interleaving rules on ETSI EN 300 401 chapter 12. * * @param vector_length length of input vectors - * @param scrambling_vector vector with scrambling parameters (see DAB standard p.138) + * @param scrambling_vector vector with scrambling parameters (see ETSI EN 300 401 chapter 12) * */ - class time_interleave_bb_impl : public time_interleave_bb - { - private: - int d_scrambling_length, d_vector_length; - std::vector d_scrambling_vector; + class time_interleave_bb_impl : public time_interleave_bb { + private: + int d_scrambling_length, d_vector_length; + std::vector d_scrambling_vector; - public: - time_interleave_bb_impl(int vector_length, const std::vector &scrambling_vector); - ~time_interleave_bb_impl(); + public: + time_interleave_bb_impl(int vector_length, const std::vector &scrambling_vector); - // Where all the action really happens - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - }; + ~time_interleave_bb_impl(); - } // namespace dab + // Where all the action really happens + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } // namespace dab } // namespace gr #endif /* INCLUDED_DAB_TIME_interleave_BB_IMPL_H */ diff --git a/lib/unpuncture_ff_impl.cc b/lib/unpuncture_ff_impl.cc deleted file mode 100644 index 8bcde8f2..00000000 --- a/lib/unpuncture_ff_impl.cc +++ /dev/null @@ -1,104 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). - * - * 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 - -#include -#include "unpuncture_ff_impl.h" - -namespace gr { - namespace dab { - - unpuncture_ff::sptr - unpuncture_ff::make(const std::vector &puncturing_vector, float fillval) - { - return gnuradio::get_initial_sptr - (new unpuncture_ff_impl(puncturing_vector, fillval)); - } - - unsigned int unpuncture_ff_impl::ones(const std::vector &puncturing_vector) - { - unsigned int onescount = 0; - for (unsigned int i = 0; i < puncturing_vector.size(); i++) { - if (puncturing_vector[i] == 1) - onescount++; - } - return onescount; - } - - /* - * The private constructor - */ - unpuncture_ff_impl::unpuncture_ff_impl(const std::vector &puncturing_vector, float fillval) - : gr::block("unpuncture_ff", - gr::io_signature::make(1, 1, sizeof(float)), - gr::io_signature::make(1, 1, sizeof(float))), - d_puncturing_vector(puncturing_vector), d_fillval(fillval) - { - d_vlen_in = ones(puncturing_vector); - d_vlen_out = puncturing_vector.size(); - set_output_multiple(d_vlen_out); - set_relative_rate(d_vlen_out / d_vlen_in); - } - - /* - * Our virtual destructor. - */ - unpuncture_ff_impl::~unpuncture_ff_impl() - { - } - - void - unpuncture_ff_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) - { - ninput_items_required[0] = noutput_items * d_vlen_in / d_vlen_out; - } - - int - unpuncture_ff_impl::general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { - int i; - unsigned int j; - - const float *in = (const float *) input_items[0]; - float *out = (float *) output_items[0]; - - for (i = 0; i < noutput_items; i++) { - if (d_puncturing_vector[i % d_vlen_out] == 1) - *out++ = *in++; - else - *out++ = d_fillval; - } - // Tell runtime system how many input items we consumed on - // each input stream. - consume_each(noutput_items * d_vlen_in / d_vlen_out); - - // Tell runtime system how many output items we produced. - return noutput_items; - } - - } /* namespace dab */ -} /* namespace gr */ - diff --git a/lib/unpuncture_vff_impl.cc b/lib/unpuncture_vff_impl.cc index 2ba57947..c86bf30e 100644 --- a/lib/unpuncture_vff_impl.cc +++ b/lib/unpuncture_vff_impl.cc @@ -35,54 +35,54 @@ namespace gr { namespace dab { -unpuncture_vff::sptr -unpuncture_vff::make(const std::vector &puncturing_vector, float fillval) -{ - return gnuradio::get_initial_sptr - (new unpuncture_vff_impl(puncturing_vector, fillval)); -} + unpuncture_vff::sptr + unpuncture_vff::make(const std::vector &puncturing_vector, + float fillval) { + return gnuradio::get_initial_sptr(new unpuncture_vff_impl(puncturing_vector, fillval)); + } -unsigned int unpuncture_vff_impl::ones (const std::vector &puncturing_vector) { - unsigned int onescount = 0; - for (unsigned int i=0; i &puncturing_vector) { + unsigned int onescount = 0; + for (unsigned int i = 0; i < puncturing_vector.size(); i++) { + if (puncturing_vector[i] == 1) + onescount++; + } + return onescount; + } -unpuncture_vff_impl::unpuncture_vff_impl(const std::vector &puncturing_vector, float fillval) - : gr::sync_block("unpuncture_vff", - gr::io_signature::make (1, 1, sizeof(float)*ones(puncturing_vector)), - gr::io_signature::make (1, 1, sizeof(float)*puncturing_vector.size())), - d_puncturing_vector(puncturing_vector), d_fillval(fillval) -{ - d_vlen_in = ones(puncturing_vector); - d_vlen_out = puncturing_vector.size(); -} + unpuncture_vff_impl::unpuncture_vff_impl( + const std::vector &puncturing_vector, float fillval) + : gr::sync_block("unpuncture_vff", + gr::io_signature::make(1, 1, sizeof(float) * ones(puncturing_vector)), + gr::io_signature::make(1, 1, sizeof(float) * puncturing_vector.size())), + d_puncturing_vector(puncturing_vector), d_fillval(fillval) { + d_vlen_in = ones(puncturing_vector); + d_vlen_out = puncturing_vector.size(); + } -int -unpuncture_vff_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - int i; - unsigned int j; - - const float *in = (const float *) input_items[0]; - float *out = (float *) output_items[0]; + int + unpuncture_vff_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { + int i; + unsigned int j; - for (i=0; i &puncturing_vector); -class unpuncture_vff_impl : public unpuncture_vff -{ - private: - unsigned int ones (const std::vector &puncturing_vector); + std::vector d_puncturing_vector; + float d_fillval; + unsigned int d_vlen_in; + unsigned int d_vlen_out; - std::vector d_puncturing_vector; - float d_fillval; - unsigned int d_vlen_in; - unsigned int d_vlen_out; + public: + unpuncture_vff_impl(const std::vector &puncturing_vector, float fillval); - public: - unpuncture_vff_impl(const std::vector &puncturing_vector, float fillval); - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; -} + } } #endif /* INCLUDED_DAB_UNPUNCTURE_VFF_H */ diff --git a/lib/valve_ff_impl.cc b/lib/valve_ff_impl.cc index 8e43c40b..182b6e97 100644 --- a/lib/valve_ff_impl.cc +++ b/lib/valve_ff_impl.cc @@ -29,61 +29,54 @@ namespace gr { namespace dab { valve_ff::sptr - valve_ff::make(bool closed, bool feed_with_zeros) - { - return gnuradio::get_initial_sptr - (new valve_ff_impl(closed, feed_with_zeros)); + valve_ff::make(bool closed, bool feed_with_zeros) { + return gnuradio::get_initial_sptr(new valve_ff_impl(closed, feed_with_zeros)); } /* * The private constructor */ valve_ff_impl::valve_ff_impl(bool closed, bool feed_with_zeros) - : gr::block("valve_ff", - gr::io_signature::make(1, 1, sizeof(float)), - gr::io_signature::make(1, 1, sizeof(float))), - d_feed_with_zeros(feed_with_zeros), d_closed(closed) - {} + : gr::block("valve_ff", + gr::io_signature::make(1, 1, sizeof(float)), + gr::io_signature::make(1, 1, sizeof(float))), + d_feed_with_zeros(feed_with_zeros), d_closed(closed) { + } /* * Our virtual destructor. */ - valve_ff_impl::~valve_ff_impl() - { + valve_ff_impl::~valve_ff_impl() { } void - valve_ff_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) - { + valve_ff_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) { ninput_items_required[0] = noutput_items; } int - valve_ff_impl::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { + valve_ff_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { const float *in = (const float *) input_items[0]; float *out = (float *) output_items[0]; - if (d_closed){ - if (d_feed_with_zeros){ + if (d_closed) { + if (d_feed_with_zeros) { // send zeros instead of the incoming floats as idle state memset(out, 0, noutput_items * sizeof(float)); - consume_each (noutput_items); + consume_each(noutput_items); return noutput_items; - } - else{ + } else { // dump incoming frames and send nothing - consume_each (noutput_items); + consume_each(noutput_items); return 0; } - } - else{ + } else { // valve opened, simply pass through the floats memcpy(out, in, noutput_items * sizeof(float)); - consume_each (noutput_items); + consume_each(noutput_items); return noutput_items; } } diff --git a/lib/valve_ff_impl.h b/lib/valve_ff_impl.h index 8294cbe8..284c8320 100644 --- a/lib/valve_ff_impl.h +++ b/lib/valve_ff_impl.h @@ -25,30 +25,32 @@ namespace gr { namespace dab { -/*! \brief lets samples pass or not depending on the state of closed - * @param feed_with_zeros if valve is closed feed_with_zeros decides if zeros are sent or nothing - * @param closed decides if valve is closed or opened +/*! \brief Lets samples pass or not depending on the state of an input variable. + * @param feed_with_zeros If valve is closed send zeros if true, else send nothing. + * @param closed Controls if valve is closed or opened. */ - class valve_ff_impl : public valve_ff - { - private: + class valve_ff_impl : public valve_ff { + private: bool d_feed_with_zeros; bool d_closed; - public: + public: valve_ff_impl(bool closed, bool feed_with_zeros); + ~valve_ff_impl(); // Where all the action really happens - void forecast (int noutput_items, gr_vector_int &ninput_items_required); + void forecast(int noutput_items, gr_vector_int &ninput_items_required); void set_closed(bool closed) { d_closed = closed; } - void set_feed_with_zeros(bool feed_with_zeros) { d_feed_with_zeros = feed_with_zeros; } + + void set_feed_with_zeros( + bool feed_with_zeros) { d_feed_with_zeros = feed_with_zeros; } int general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; } // namespace dab diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 193482b1..1eff45eb 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -25,7 +25,6 @@ if(NOT PYTHONINTERP_FOUND) return() endif() - ######################################################################## # Insert ICON PATH macro Insert ICON PATH macro into constants.py ######################################################################## @@ -43,18 +42,17 @@ configure_file( GR_PYTHON_INSTALL( FILES __init__.py - ofdm_sync_dab.py - ofdm_sync_dab2.py - detect_null.py - ofdm.py + ofdm_mod_bc.py + ofdm_demod_cc.py parameters.py - fic.py - msc_decode.py fic_encode.py msc_encode.py + fic_decode_vc.py + msc_decode.py transmitter_c.py ${CMAKE_CURRENT_BINARY_DIR}/constants.py - dabplus_audio_decoder_ff.py DESTINATION ${GR_PYTHON_DIR}/dab + dabplus_audio_decoder_ff.py + DESTINATION ${GR_PYTHON_DIR}/dab ) ######################################################################## @@ -64,26 +62,31 @@ include(GrTest) set(GR_TEST_TARGET_DEPS gnuradio-dab) set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig) -GR_ADD_TEST(qa_time_interleave_bb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_time_interleave_bb.py) -GR_ADD_TEST(qa_time_deinterleave_ff ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_time_deinterleave_ff.py) -GR_ADD_TEST(qa_fib_sink_vb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_fib_sink_vb.py) -GR_ADD_TEST(qa_crc16_bb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_crc16_bb.py) -GR_ADD_TEST(qa_fib_source_b ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_fib_source_b.py) -GR_ADD_TEST(qa_select_subch_vfvf ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_select_subch_vfvf.py) -GR_ADD_TEST(qa_unpuncture_ff ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_unpuncture_ff.py) -GR_ADD_TEST(qa_prune ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_prune.py) -GR_ADD_TEST(qa_fic_encode ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_fic_encode.py) -GR_ADD_TEST(qa_puncture_bb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_puncture_bb.py) -GR_ADD_TEST(qa_msc_encode ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_msc_encode.py) -GR_ADD_TEST(qa_dab_transmission_frame_mux_bb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_dab_transmission_frame_mux_bb.py) -GR_ADD_TEST(qa_conv_encoder_bb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_conv_encoder_bb.py) -GR_ADD_TEST(qa_mapper_bc ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_mapper_bc.py) -GR_ADD_TEST(qa_mp2_decode_bs ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_mp2_decode_bs.py) -GR_ADD_TEST(qa_mp4_decode_bs ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_mp4_decode_bs.py) -GR_ADD_TEST(qa_dabplus_audio_decoder_ff ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_dabplus_audio_decoder_ff.py) -GR_ADD_TEST(qa_reed_solomon_decode_bb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_reed_solomon_decode_bb.py) -GR_ADD_TEST(qa_reed_solomon_encode_bb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_reed_solomon_encode_bb.py) -GR_ADD_TEST(qa_mp4_encode_sb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_mp4_encode_sb.py) -GR_ADD_TEST(qa_mp2_encode_sb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_mp2_encode_sb.py) + +GR_ADD_TEST(qa_qpsk_mapper_vbvc.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_qpsk_mapper_vbvc.py) +GR_ADD_TEST(qa_ofdm_insert_pilot.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_ofdm_insert_pilot.py) +GR_ADD_TEST(qa_sum_phasor_trig_vcc.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_sum_phasor_trig_vcc.py) +GR_ADD_TEST(qa_frequency_interleaver_vcc.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_frequency_interleaver_vcc.py) +GR_ADD_TEST(qa_ofdm_move_and_insert_zero.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_ofdm_move_and_insert_zero.py) +GR_ADD_TEST(qa_insert_null_symbol.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_insert_null_symbol.py) +GR_ADD_TEST(qa_fib_source_b.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_fib_source_b.py) +GR_ADD_TEST(qa_fic_encode.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_fic_encode.py) +GR_ADD_TEST(qa_crc16_bb.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_crc16_bb.py) +GR_ADD_TEST(qa_conv_encoder_bb.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_conv_encoder_bb.py) +GR_ADD_TEST(qa_puncture_bb.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_puncture_bb.py) +GR_ADD_TEST(qa_mp4_encode_sb.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_mp4_encode_sb.py) +GR_ADD_TEST(qa_reed_solomon_encode_bb.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_reed_solomon_encode_bb.py) +GR_ADD_TEST(qa_msc_encode.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_msc_encode.py) +GR_ADD_TEST(qa_time_interleave_bb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_time_interleave_bb.py) +GR_ADD_TEST(qa_dab_transmission_frame_mux_bb.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_dab_transmission_frame_mux_bb.py) +GR_ADD_TEST(qa_diff_phasor_vcc.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_diff_phasor_vcc.py) +GR_ADD_TEST(qa_complex_to_interleaved_float_vcf.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_complex_to_interleaved_float_vcf.py) +GR_ADD_TEST(qa_select_cus_vfvf ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_select_cus_vfvf.py) +GR_ADD_TEST(qa_unpuncture_vff ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_unpuncture_vff.py) +GR_ADD_TEST(qa_prune.py ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_prune.py) +GR_ADD_TEST(qa_fib_sink_vb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_fib_sink_vb.py) +GR_ADD_TEST(qa_time_deinterleave_ff ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_time_deinterleave_ff.py) +GR_ADD_TEST(qa_reed_solomon_decode_bb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_reed_solomon_decode_bb.py) +GR_ADD_TEST(qa_mp4_decode_bs ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa/qa_mp4_decode_bs.py) GR_ADD_TEST(qa_valve_ff ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_valve_ff.py) -GR_ADD_TEST(qa_peak_detector_fb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_peak_detector_fb.py) + diff --git a/python/GUI/CMakeLists.txt b/python/GUI/CMakeLists.txt index e243f8bb..c2b6abb7 100644 --- a/python/GUI/CMakeLists.txt +++ b/python/GUI/CMakeLists.txt @@ -19,19 +19,30 @@ include(GrPython) +######################################################################## +# Generate the GUI python code user_frontend.py from the user interface user_frontend.ui +######################################################################## +set(GUI_UI ${CMAKE_CURRENT_SOURCE_DIR}/user_frontend.ui) +set(GUI_PY ${CMAKE_CURRENT_BINARY_DIR}/user_frontend.py) +add_custom_command(OUTPUT ${GUI_PY} + COMMAND ${PYUIC4_EXECUTABLE} ${GUI_UI} -o ${GUI_PY} + DEPENDS ${GUI_UI} + COMMENT "Generating python code from the user interface" +) GR_PYTHON_INSTALL( FILES usrp_dab_rx.py usrp_dab_tx.py - user_frontend.py + ${GUI_PY} DESTINATION ${GR_PYTHON_DIR}/dab COMPONENT "dab_python" ) set(GR_PKG_DAB_DATA_DIR ${GR_PKG_DATA_DIR}) -install(FILES +install(FILES DAB_logo.png led_red.png led_orange.png - led_green.png - DESTINATION ${GR_PKG_DAB_DATA_DIR} + led_green.png + DESTINATION ${GR_PKG_DAB_DATA_DIR} ) + diff --git a/python/GUI/frontend.py b/python/GUI/frontend.py deleted file mode 100644 index 9894632e..00000000 --- a/python/GUI/frontend.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'frontend.ui' -# -# Created by: PyQt4 UI code generator 4.11.4 -# -# WARNING! All changes made in this file will be lost! - diff --git a/python/GUI/main.py b/python/GUI/main.py index dfe21939..04927a5a 100644 --- a/python/GUI/main.py +++ b/python/GUI/main.py @@ -51,6 +51,7 @@ def __init__(self, parent=None): self.need_new_init = True self.file_path = "None" self.src_is_USRP = True + self.src_is_RTL = False self.receiver_running = False self.audio_playing = False self.recording = False @@ -70,6 +71,7 @@ def __init__(self, parent=None): self.snr_timer.timeout.connect(self.snr_update) # change of source by radio buttons self.rbtn_USRP.clicked.connect(self.src2USRP) + self.rbtn_RTL.clicked.connect(self.src2RTL) self.rbtn_File.clicked.connect(self.src2File) # set file path self.btn_file_path.clicked.connect(self.set_file_path) @@ -84,6 +86,8 @@ def __init__(self, parent=None): # adjust audio sampling rate self.timer_audio_sampling_rate = QTimer() self.timer_audio_sampling_rate.timeout.connect(self.adjust_audio_sampling_rate) + # gain setter + self.gain_spin.valueChanged.connect(self.set_rx_gain) # stop button click stops audio reception self.btn_stop.hide() self.btn_stop.clicked.connect(self.stop_audio) @@ -176,6 +180,8 @@ def __init__(self, parent=None): self.t_btn_stop.pressed.connect(self.t_stop_transmitter) # path for File sink path self.t_btn_file_path.pressed.connect(self.t_set_file_path) + # gain setter + self.tx_gain.valueChanged.connect(self.set_tx_gain) # path selection for all 7 (possible) sub channels self.t_btn_path_src1.pressed.connect(self.t_set_subch_path1) self.t_btn_path_src2.pressed.connect(self.t_set_subch_path2) @@ -200,6 +206,7 @@ def __init__(self, parent=None): self.t_combo_dabplus7.currentIndexChanged.connect(self.change_audio_bit_rates7) # set volume if volume slider is changed self.t_slider_volume.valueChanged.connect(self.t_set_volume) + self.transmitter_running = False ################################ # general functions @@ -225,6 +232,16 @@ def src2USRP(self): self.spinbox_frequency.setEnabled(True) self.label_frequency.setEnabled(True) self.src_is_USRP = True + self.src_is_RTL = False + + def src2RTL(self): + # enable/disable buttons + self.btn_file_path.setEnabled(False) + self.label_path.setEnabled(False) + self.spinbox_frequency.setEnabled(True) + self.label_frequency.setEnabled(True) + self.src_is_RTL = True + self.src_is_USRP = False def src2File(self): # enable/disable buttons @@ -233,6 +250,7 @@ def src2File(self): self.spinbox_frequency.setEnabled(False) self.label_frequency.setEnabled(False) self.src_is_USRP = False + self.src_is_RTL = False def set_file_path(self): path = QtGui.QFileDialog.getOpenFileName(self, "Pick a file with recorded IQ samples") @@ -247,13 +265,13 @@ def init_receiver(self): self.snr_timer.stop() self.firecode_timer.stop() # check if file path is selected in case that file is the selected source - if (not self.src_is_USRP) and (self.file_path == "None"): + if (not self.src_is_USRP) and (not self.src_is_RTL) and (self.file_path == "None"): self.label_path.setStyleSheet('color: red') else: self.label_path.setStyleSheet('color: black') # set up and start flowgraph self.my_receiver = usrp_dab_rx.usrp_dab_rx(self.spin_dab_mode.value(), self.spinbox_frequency.value(), self.bit_rate, self.address, self.size, self.protection, self.audio_bit_rate, self.dabplus, - self.src_is_USRP, self.file_path) + self.src_is_USRP, self.src_is_RTL, self.file_path) self.my_receiver.set_volume(0) self.my_receiver.start() # status bar @@ -275,6 +293,11 @@ def init_receiver(self): self.receiver_running = True self.btn_init.setText("stop receiver") else: + # stop receiver was pressed + self.dev_mode_close() + # remove service table + while (self.table_mci.rowCount() > 0): + self.table_mci.removeRow(0) self.my_receiver.stop() self.receiver_running = False self.btn_init.setText("start receiver") @@ -287,6 +310,21 @@ def init_receiver(self): self.btn_stop.hide() self.audio_playing = False self.statusBar.showMessage("Receiver stopped.") + self.bar_snr.setValue(0) + # reset variables + self.bit_rate = 8 + self.address = 0 + self.size = 6 + self.protection = 2 + self.audio_bit_rate = 16000 + self.volume = 80 + self.subch = -1 + self.dabplus = True + self.need_new_init = True + self.file_path = "None" + self.receiver_running = False + self.audio_playing = False + self.recording = False def update_service_info(self): # set status bar message @@ -372,25 +410,25 @@ def selected_subch(self): self.statusBar.showMessage("Play/Record the selected service component.") def snr_update(self): - print "update snr" # display snr in progress bar if an instance of usrp_dab_rx is existing - if hasattr(self, 'my_receiver'): + if hasattr(self, 'my_receiver') and self.receiver_running: SNR = self.my_receiver.get_snr() - if SNR > 10: + if SNR > 15.0: self.setStyleSheet("""QProgressBar::chunk { background: "green"; }""") - if SNR > 20: - SNR = 20 - elif 5 < SNR <= 10: + elif SNR > 10.0: self.setStyleSheet("""QProgressBar::chunk { background: "yellow"; }""") - else: + elif SNR <= 10.0: self.setStyleSheet("""QProgressBar::chunk { background: "red"; }""") - if SNR < -20 or math.isnan(SNR): - SNR = -20 - self.bar_snr.setValue(SNR) self.lcd_snr.display(SNR) + if SNR > 40: + SNR = 20 + elif SNR < 0: + SNR = 0 + self.bar_snr.setValue(int(SNR)) + else: - self.bar_snr.setValue(-20) - self.label_snr.setText("SNR: no reception") + self.bar_snr.setValue(0) + #self.label_snr.setText("SNR: no reception") self.snr_timer.start(1000) def play_audio(self): @@ -405,11 +443,12 @@ def play_audio(self): self.snr_timer.stop() self.firecode_timer.stop() self.my_receiver.stop() + self.temp_src = self.my_receiver.src self.my_receiver = usrp_dab_rx.usrp_dab_rx(self.spin_dab_mode.value(), self.spinbox_frequency.value(), self.bit_rate, self.address, self.size, self.protection, self.audio_bit_rate, self.dabplus, - self.src_is_USRP, self.file_path) + self.src_is_USRP, self.src_is_RTL, self.file_path, prev_src=self.temp_src) self.my_receiver.set_volume(float(self.slider_volume.value()) / 100) self.my_receiver.start() self.statusBar.showMessage("Audio playing.") @@ -436,7 +475,6 @@ def stop_audio(self): def adjust_audio_sampling_rate(self): self.timer_audio_sampling_rate.stop() new_sampling_rate = self.my_receiver.get_sample_rate() - print "key adjust" if new_sampling_rate != self.audio_bit_rate and new_sampling_rate != -1: self.audio_bit_rate = new_sampling_rate self.statusBar.showMessage("Adjusting audio sampling rate to " + str(new_sampling_rate)) @@ -445,7 +483,7 @@ def adjust_audio_sampling_rate(self): self.spinbox_frequency.value(), self.bit_rate, self.address, self.size, self.protection, self.audio_bit_rate, self.dabplus, - self.src_is_USRP, self.file_path) + self.src_is_USRP, self.src_is_RTL, self.file_path, prev_src=self.temp_src) self.my_receiver.start() elif new_sampling_rate == -1: @@ -704,81 +742,87 @@ def t_update_service_components(self): component["combo_audio_rate"].hide() def t_init_transmitter(self): - self.statusBar.showMessage("initializing transmitter...") - # boolean is set to True if info is missing to init the transmitter - arguments_incomplete = False - # produce array for protection and data_rate and src_paths and stereo flags - num_subch = self.t_spin_num_subch.value() - protection_array = [None] * num_subch - data_rate_n_array = [None] * num_subch - audio_sampling_rate_array = [None] * num_subch - audio_paths = [None] * num_subch - stereo_flags = [None] * num_subch - merged_service_string = "" - dabplus_types = [True] * num_subch - record_states = [False] * num_subch - for i in range(0, num_subch): - # write array with protection modes - protection_array[i] = self.components[i]["protection"].currentIndex() - # write array with data rates - data_rate_n_array[i] = self.components[i]["data_rate"].value()/8 - # write stereo flags - stereo_flags[i] = self.components[i]["combo_stereo"].currentIndex() - # write audio sampling rates in array - if self.components[i]["combo_dabplus"].currentIndex() is 0: - audio_sampling_rate_array[i] = 32000 if (self.components[i]["combo_audio_rate"].currentIndex() is 0) else 48000 - else: - audio_sampling_rate_array[i] = 48000 if (self.components[i]["combo_audio_rate_dab"].currentIndex() is 0) else 24000 - # check audio paths - if self.components[i]["src_path"] is "None": - # highlight the path which is not selected - self.components[i]["src_path_disp"].setStyleSheet('color: red') - arguments_incomplete = True - self.statusBar.showMessage("path " + str(i+1) + " not selected") - # check if length of label is <= 16 chars - elif len(str(self.components[i]["edit_label"].text())) > 16: - self.components[i]["edit_label"].setStyleSheet('color: red') + if self.transmitter_running: + self.transmitter_running = False + self.t_btn_init.setText("start transmitter") + else: + self.transmitter_running = True + self.t_btn_init.setText("stop transmitter") + self.statusBar.showMessage("initializing transmitter...") + # boolean is set to True if info is missing to init the transmitter + arguments_incomplete = False + # produce array for protection and data_rate and src_paths and stereo flags + num_subch = self.t_spin_num_subch.value() + protection_array = [None] * num_subch + data_rate_n_array = [None] * num_subch + audio_sampling_rate_array = [None] * num_subch + audio_paths = [None] * num_subch + stereo_flags = [None] * num_subch + merged_service_string = "" + dabplus_types = [True] * num_subch + record_states = [False] * num_subch + for i in range(0, num_subch): + # write array with protection modes + protection_array[i] = self.components[i]["protection"].currentIndex() + # write array with data rates + data_rate_n_array[i] = self.components[i]["data_rate"].value()/8 + # write stereo flags + stereo_flags[i] = self.components[i]["combo_stereo"].currentIndex() + # write audio sampling rates in array + if self.components[i]["combo_dabplus"].currentIndex() is 0: + audio_sampling_rate_array[i] = 32000 if (self.components[i]["combo_audio_rate"].currentIndex() is 0) else 48000 + else: + audio_sampling_rate_array[i] = 48000 if (self.components[i]["combo_audio_rate_dab"].currentIndex() is 0) else 24000 + # check audio paths + if self.components[i]["src_path"] is "None": + # highlight the path which is not selected + self.components[i]["src_path_disp"].setStyleSheet('color: red') + arguments_incomplete = True + self.statusBar.showMessage("path " + str(i+1) + " not selected") + # check if length of label is <= 16 chars + elif len(str(self.components[i]["edit_label"].text())) > 16: + self.components[i]["edit_label"].setStyleSheet('color: red') + arguments_incomplete = True + self.statusBar.showMessage("Warning: Label is longer than 16 characters!") + else: + audio_paths[i] = self.components[i]["src_path"] + # write service labels appended in one string + merged_service_string = merged_service_string + str(self.components[i]["edit_label"].text()).ljust(16) + self.components[i]["edit_label"].setStyleSheet('color: black') + # write dabplus types + dabplus_types[i] = (1 if self.components[i]["combo_dabplus"].currentIndex() is 0 else 0) + + # check if length of ensemble label is <= 16 chars + if len(str(self.t_edit_ensemble_label.text())) > 16: + self.t_edit_ensemble_label.setStyleSheet('color: red') arguments_incomplete = True - self.statusBar.showMessage("Warning: Label is longer than 16 characters!") else: - audio_paths[i] = self.components[i]["src_path"] - # write service labels appended in one string - merged_service_string = merged_service_string + str(self.components[i]["edit_label"].text()).ljust(16) - self.components[i]["edit_label"].setStyleSheet('color: black') - # write dabplus types - dabplus_types[i] = (1 if self.components[i]["combo_dabplus"].currentIndex() is 0 else 0) - - # check if length of ensemble label is <= 16 chars - if len(str(self.t_edit_ensemble_label.text())) > 16: - self.t_edit_ensemble_label.setStyleSheet('color: red') - arguments_incomplete = True - else: - self.t_edit_ensemble_label.setStyleSheet('color: black') - # check if File path for sink is chosen if option enabled - if self.t_rbtn_File.isChecked() and (str(self.t_label_sink.text()) == "select path"): - self.t_label_sink.setStyleSheet('color: red') - arguments_incomplete = True - - if arguments_incomplete is False: - # init transmitter - self.my_transmitter = usrp_dab_tx.usrp_dab_tx(self.t_spin_dab_mode.value(), - self.t_spinbox_frequency.value(), - self.t_spin_num_subch.value(), - str(self.t_edit_ensemble_label.text()), - merged_service_string, - self.t_combo_language.currentIndex(), self.t_combo_country.currentIndex(), - protection_array, data_rate_n_array, stereo_flags, audio_sampling_rate_array, - audio_paths, - self.t_spin_listen_to_component.value(), - self.t_rbtn_USRP.isChecked(), - dabplus_types, - str(self.t_label_sink.text()) + "/" + str( - self.t_edit_file_name.text())) - - # enable play button - self.t_btn_play.setEnabled(True) - self.t_label_status.setText("ready to transmit") - self.statusBar.showMessage("ready to transmit") + self.t_edit_ensemble_label.setStyleSheet('color: black') + # check if File path for sink is chosen if option enabled + if self.t_rbtn_File.isChecked() and (str(self.t_label_sink.text()) == "select path"): + self.t_label_sink.setStyleSheet('color: red') + arguments_incomplete = True + + if arguments_incomplete is False: + # init transmitter + self.my_transmitter = usrp_dab_tx.usrp_dab_tx(self.t_spin_dab_mode.value(), + self.t_spinbox_frequency.value(), + self.t_spin_num_subch.value(), + str(self.t_edit_ensemble_label.text()), + merged_service_string, + self.t_combo_language.currentIndex(), self.t_combo_country.currentIndex(), + protection_array, data_rate_n_array, stereo_flags, audio_sampling_rate_array, + audio_paths, + self.t_spin_listen_to_component.value(), + self.t_rbtn_USRP.isChecked(), + dabplus_types, + str(self.t_label_sink.text()) + "/" + str( + self.t_edit_file_name.text())) + + # enable play button + self.t_btn_play.setEnabled(True) + self.t_label_status.setText("ready to transmit") + self.statusBar.showMessage("ready to transmit") def t_run_transmitter(self): self.t_btn_stop.setEnabled(True) @@ -953,6 +997,14 @@ def change_audio_bit_rates7(self): self.t_combo_audio_rate_dab7.show() self.t_combo_audio_rate7.hide() + def set_rx_gain(self): + if hasattr(self, 'my_receiver'): + self.my_receiver.set_gain(self.gain_spin.value()) + + def set_tx_gain(self): + if hasattr(self, 'my_transmitter'): + self.my_transmitter.set_gain(self.tx_gain.value()) + class lookup_tables: languages = [ diff --git a/python/GUI/user_frontend.py b/python/GUI/user_frontend.py deleted file mode 100644 index 17557942..00000000 --- a/python/GUI/user_frontend.py +++ /dev/null @@ -1,1569 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'user_frontend.ui' -# -# Created by: PyQt4 UI code generator 4.11.4 -# -# WARNING! All changes made in this file will be lost! - -from PyQt4 import QtCore, QtGui - -try: - _fromUtf8 = QtCore.QString.fromUtf8 -except AttributeError: - def _fromUtf8(s): - return s - -try: - _encoding = QtGui.QApplication.UnicodeUTF8 - def _translate(context, text, disambig): - return QtGui.QApplication.translate(context, text, disambig, _encoding) -except AttributeError: - def _translate(context, text, disambig): - return QtGui.QApplication.translate(context, text, disambig) - -class Ui_MainWindow(object): - def setupUi(self, MainWindow): - MainWindow.setObjectName(_fromUtf8("MainWindow")) - MainWindow.resize(1146, 739) - self.centralwidget = QtGui.QWidget(MainWindow) - self.centralwidget.setEnabled(True) - self.centralwidget.setObjectName(_fromUtf8("centralwidget")) - self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget) - self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) - self.horizontalLayout_21 = QtGui.QHBoxLayout() - self.horizontalLayout_21.setObjectName(_fromUtf8("horizontalLayout_21")) - self.label_5 = QtGui.QLabel(self.centralwidget) - self.label_5.setObjectName(_fromUtf8("label_5")) - self.horizontalLayout_21.addWidget(self.label_5) - self.label_logo = QtGui.QLabel(self.centralwidget) - self.label_logo.setObjectName(_fromUtf8("label_logo")) - self.horizontalLayout_21.addWidget(self.label_logo) - spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.horizontalLayout_21.addItem(spacerItem) - self.btn_dev_mode_close = QtGui.QPushButton(self.centralwidget) - self.btn_dev_mode_close.setEnabled(True) - icon = QtGui.QIcon.fromTheme(_fromUtf8("list-remove")) - self.btn_dev_mode_close.setIcon(icon) - self.btn_dev_mode_close.setObjectName(_fromUtf8("btn_dev_mode_close")) - self.horizontalLayout_21.addWidget(self.btn_dev_mode_close) - self.btn_dev_mode_open = QtGui.QPushButton(self.centralwidget) - self.btn_dev_mode_open.setEnabled(False) - icon = QtGui.QIcon.fromTheme(_fromUtf8("list-add")) - self.btn_dev_mode_open.setIcon(icon) - self.btn_dev_mode_open.setObjectName(_fromUtf8("btn_dev_mode_open")) - self.horizontalLayout_21.addWidget(self.btn_dev_mode_open) - self.verticalLayout.addLayout(self.horizontalLayout_21) - self.mode_tabs = QtGui.QTabWidget(self.centralwidget) - self.mode_tabs.setEnabled(True) - self.mode_tabs.setObjectName(_fromUtf8("mode_tabs")) - self.tab_reception = QtGui.QWidget() - self.tab_reception.setObjectName(_fromUtf8("tab_reception")) - self.verticalLayout_2 = QtGui.QVBoxLayout(self.tab_reception) - self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) - self.horizontal_layout_reception = QtGui.QHBoxLayout() - self.horizontal_layout_reception.setObjectName(_fromUtf8("horizontal_layout_reception")) - self.verticalLayout_6 = QtGui.QVBoxLayout() - self.verticalLayout_6.setObjectName(_fromUtf8("verticalLayout_6")) - self.horizontalLayout_8 = QtGui.QHBoxLayout() - self.horizontalLayout_8.setObjectName(_fromUtf8("horizontalLayout_8")) - self.verticalLayout_6.addLayout(self.horizontalLayout_8) - self.horizontalLayout = QtGui.QHBoxLayout() - self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) - self.rbtn_USRP = QtGui.QRadioButton(self.tab_reception) - self.rbtn_USRP.setChecked(True) - self.rbtn_USRP.setAutoRepeat(False) - self.rbtn_USRP.setObjectName(_fromUtf8("rbtn_USRP")) - self.horizontalLayout.addWidget(self.rbtn_USRP) - spacerItem1 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.horizontalLayout.addItem(spacerItem1) - self.label_frequency = QtGui.QLabel(self.tab_reception) - self.label_frequency.setObjectName(_fromUtf8("label_frequency")) - self.horizontalLayout.addWidget(self.label_frequency) - self.spinbox_frequency = QtGui.QSpinBox(self.tab_reception) - self.spinbox_frequency.setMaximum(1000000000) - self.spinbox_frequency.setProperty("value", 208064000) - self.spinbox_frequency.setObjectName(_fromUtf8("spinbox_frequency")) - self.horizontalLayout.addWidget(self.spinbox_frequency) - self.label_4 = QtGui.QLabel(self.tab_reception) - self.label_4.setObjectName(_fromUtf8("label_4")) - self.horizontalLayout.addWidget(self.label_4) - self.verticalLayout_6.addLayout(self.horizontalLayout) - self.horizontalLayout_6 = QtGui.QHBoxLayout() - self.horizontalLayout_6.setObjectName(_fromUtf8("horizontalLayout_6")) - self.rbtn_File = QtGui.QRadioButton(self.tab_reception) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.rbtn_File.sizePolicy().hasHeightForWidth()) - self.rbtn_File.setSizePolicy(sizePolicy) - self.rbtn_File.setObjectName(_fromUtf8("rbtn_File")) - self.horizontalLayout_6.addWidget(self.rbtn_File) - self.label_path = QtGui.QLabel(self.tab_reception) - self.label_path.setEnabled(False) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_path.sizePolicy().hasHeightForWidth()) - self.label_path.setSizePolicy(sizePolicy) - self.label_path.setMinimumSize(QtCore.QSize(100, 0)) - self.label_path.setFrameShape(QtGui.QFrame.Box) - self.label_path.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.label_path.setObjectName(_fromUtf8("label_path")) - self.horizontalLayout_6.addWidget(self.label_path) - self.btn_file_path = QtGui.QToolButton(self.tab_reception) - self.btn_file_path.setEnabled(False) - self.btn_file_path.setObjectName(_fromUtf8("btn_file_path")) - self.horizontalLayout_6.addWidget(self.btn_file_path) - self.verticalLayout_6.addLayout(self.horizontalLayout_6) - self.horizontalLayout_30 = QtGui.QHBoxLayout() - self.horizontalLayout_30.setObjectName(_fromUtf8("horizontalLayout_30")) - spacerItem2 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.horizontalLayout_30.addItem(spacerItem2) - self.label_6 = QtGui.QLabel(self.tab_reception) - self.label_6.setObjectName(_fromUtf8("label_6")) - self.horizontalLayout_30.addWidget(self.label_6) - self.spin_dab_mode = QtGui.QSpinBox(self.tab_reception) - self.spin_dab_mode.setMinimum(1) - self.spin_dab_mode.setMaximum(4) - self.spin_dab_mode.setObjectName(_fromUtf8("spin_dab_mode")) - self.horizontalLayout_30.addWidget(self.spin_dab_mode) - self.verticalLayout_6.addLayout(self.horizontalLayout_30) - self.horizontalLayout_3 = QtGui.QHBoxLayout() - self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3")) - self.verticalLayout_6.addLayout(self.horizontalLayout_3) - self.table_mci = QtGui.QTableWidget(self.tab_reception) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.table_mci.sizePolicy().hasHeightForWidth()) - self.table_mci.setSizePolicy(sizePolicy) - self.table_mci.setObjectName(_fromUtf8("table_mci")) - self.table_mci.setColumnCount(4) - self.table_mci.setRowCount(0) - item = QtGui.QTableWidgetItem() - self.table_mci.setHorizontalHeaderItem(0, item) - item = QtGui.QTableWidgetItem() - self.table_mci.setHorizontalHeaderItem(1, item) - item = QtGui.QTableWidgetItem() - self.table_mci.setHorizontalHeaderItem(2, item) - item = QtGui.QTableWidgetItem() - self.table_mci.setHorizontalHeaderItem(3, item) - self.table_mci.horizontalHeader().setCascadingSectionResizes(False) - self.table_mci.horizontalHeader().setDefaultSectionSize(100) - self.table_mci.horizontalHeader().setStretchLastSection(True) - self.verticalLayout_6.addWidget(self.table_mci) - self.horizontal_layout_reception.addLayout(self.verticalLayout_6) - self.line_8 = QtGui.QFrame(self.tab_reception) - self.line_8.setFrameShape(QtGui.QFrame.VLine) - self.line_8.setFrameShadow(QtGui.QFrame.Sunken) - self.line_8.setObjectName(_fromUtf8("line_8")) - self.horizontal_layout_reception.addWidget(self.line_8) - self.verticalLayout_7 = QtGui.QVBoxLayout() - self.verticalLayout_7.setObjectName(_fromUtf8("verticalLayout_7")) - self.horizontalLayout_27 = QtGui.QHBoxLayout() - self.horizontalLayout_27.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint) - self.horizontalLayout_27.setSpacing(6) - self.horizontalLayout_27.setObjectName(_fromUtf8("horizontalLayout_27")) - self.label_ensemble = QtGui.QLabel(self.tab_reception) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_ensemble.sizePolicy().hasHeightForWidth()) - self.label_ensemble.setSizePolicy(sizePolicy) - font = QtGui.QFont() - font.setPointSize(17) - self.label_ensemble.setFont(font) - self.label_ensemble.setAlignment(QtCore.Qt.AlignCenter) - self.label_ensemble.setObjectName(_fromUtf8("label_ensemble")) - self.horizontalLayout_27.addWidget(self.label_ensemble) - self.verticalLayout_10 = QtGui.QVBoxLayout() - self.verticalLayout_10.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint) - self.verticalLayout_10.setObjectName(_fromUtf8("verticalLayout_10")) - self.horizontalLayout_28 = QtGui.QHBoxLayout() - self.horizontalLayout_28.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint) - self.horizontalLayout_28.setObjectName(_fromUtf8("horizontalLayout_28")) - self.label_26 = QtGui.QLabel(self.tab_reception) - self.label_26.setObjectName(_fromUtf8("label_26")) - self.horizontalLayout_28.addWidget(self.label_26) - self.lcd_number_num_subch = QtGui.QLCDNumber(self.tab_reception) - self.lcd_number_num_subch.setEnabled(True) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.lcd_number_num_subch.sizePolicy().hasHeightForWidth()) - self.lcd_number_num_subch.setSizePolicy(sizePolicy) - self.lcd_number_num_subch.setNumDigits(2) - self.lcd_number_num_subch.setSegmentStyle(QtGui.QLCDNumber.Flat) - self.lcd_number_num_subch.setObjectName(_fromUtf8("lcd_number_num_subch")) - self.horizontalLayout_28.addWidget(self.lcd_number_num_subch) - self.verticalLayout_10.addLayout(self.horizontalLayout_28) - self.label_country = QtGui.QLabel(self.tab_reception) - self.label_country.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.label_country.setObjectName(_fromUtf8("label_country")) - self.verticalLayout_10.addWidget(self.label_country) - self.horizontalLayout_27.addLayout(self.verticalLayout_10) - self.verticalLayout_7.addLayout(self.horizontalLayout_27) - self.line_11 = QtGui.QFrame(self.tab_reception) - self.line_11.setFrameShape(QtGui.QFrame.HLine) - self.line_11.setFrameShadow(QtGui.QFrame.Sunken) - self.line_11.setObjectName(_fromUtf8("line_11")) - self.verticalLayout_7.addWidget(self.line_11) - spacerItem3 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - self.verticalLayout_7.addItem(spacerItem3) - self.horizontalLayout_23 = QtGui.QHBoxLayout() - self.horizontalLayout_23.setObjectName(_fromUtf8("horizontalLayout_23")) - self.bar_snr = QtGui.QProgressBar(self.tab_reception) - self.bar_snr.setStyleSheet(_fromUtf8("tfadsf")) - self.bar_snr.setMinimum(-20) - self.bar_snr.setMaximum(20) - self.bar_snr.setProperty("value", 0) - self.bar_snr.setFormat(_fromUtf8("")) - self.bar_snr.setObjectName(_fromUtf8("bar_snr")) - self.horizontalLayout_23.addWidget(self.bar_snr) - self.label_snr = QtGui.QLabel(self.tab_reception) - self.label_snr.setObjectName(_fromUtf8("label_snr")) - self.horizontalLayout_23.addWidget(self.label_snr) - self.lcd_snr = QtGui.QLCDNumber(self.tab_reception) - self.lcd_snr.setSmallDecimalPoint(False) - self.lcd_snr.setNumDigits(4) - self.lcd_snr.setSegmentStyle(QtGui.QLCDNumber.Flat) - self.lcd_snr.setObjectName(_fromUtf8("lcd_snr")) - self.horizontalLayout_23.addWidget(self.lcd_snr) - self.label_7 = QtGui.QLabel(self.tab_reception) - self.label_7.setObjectName(_fromUtf8("label_7")) - self.horizontalLayout_23.addWidget(self.label_7) - self.verticalLayout_7.addLayout(self.horizontalLayout_23) - self.vertical_layout_dev_mode_right_vertical = QtGui.QVBoxLayout() - self.vertical_layout_dev_mode_right_vertical.setObjectName(_fromUtf8("vertical_layout_dev_mode_right_vertical")) - self.horizontalLayout_29 = QtGui.QHBoxLayout() - self.horizontalLayout_29.setObjectName(_fromUtf8("horizontalLayout_29")) - self.label_firecode = QtGui.QLabel(self.tab_reception) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.label_firecode.sizePolicy().hasHeightForWidth()) - self.label_firecode.setSizePolicy(sizePolicy) - self.label_firecode.setMinimumSize(QtCore.QSize(365, 80)) - self.label_firecode.setMaximumSize(QtCore.QSize(365, 80)) - self.label_firecode.setFrameShape(QtGui.QFrame.Box) - self.label_firecode.setFrameShadow(QtGui.QFrame.Sunken) - self.label_firecode.setLineWidth(2) - self.label_firecode.setMidLineWidth(0) - self.label_firecode.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) - self.label_firecode.setObjectName(_fromUtf8("label_firecode")) - self.horizontalLayout_29.addWidget(self.label_firecode) - self.verticalLayout_13 = QtGui.QVBoxLayout() - self.verticalLayout_13.setObjectName(_fromUtf8("verticalLayout_13")) - spacerItem4 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - self.verticalLayout_13.addItem(spacerItem4) - self.led_msc = QtGui.QLabel(self.tab_reception) - self.led_msc.setObjectName(_fromUtf8("led_msc")) - self.verticalLayout_13.addWidget(self.led_msc) - spacerItem5 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - self.verticalLayout_13.addItem(spacerItem5) - self.horizontalLayout_29.addLayout(self.verticalLayout_13) - self.label_label_msc = QtGui.QLabel(self.tab_reception) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.label_label_msc.setFont(font) - self.label_label_msc.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) - self.label_label_msc.setObjectName(_fromUtf8("label_label_msc")) - self.horizontalLayout_29.addWidget(self.label_label_msc) - spacerItem6 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.horizontalLayout_29.addItem(spacerItem6) - self.vertical_layout_dev_mode_right_vertical.addLayout(self.horizontalLayout_29) - self.horizontalLayout_32 = QtGui.QHBoxLayout() - self.horizontalLayout_32.setObjectName(_fromUtf8("horizontalLayout_32")) - self.label_fic = QtGui.QLabel(self.tab_reception) - self.label_fic.setMinimumSize(QtCore.QSize(365, 80)) - self.label_fic.setMaximumSize(QtCore.QSize(365, 80)) - self.label_fic.setFrameShape(QtGui.QFrame.Box) - self.label_fic.setFrameShadow(QtGui.QFrame.Sunken) - self.label_fic.setLineWidth(2) - self.label_fic.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop) - self.label_fic.setObjectName(_fromUtf8("label_fic")) - self.horizontalLayout_32.addWidget(self.label_fic) - self.verticalLayout_14 = QtGui.QVBoxLayout() - self.verticalLayout_14.setObjectName(_fromUtf8("verticalLayout_14")) - spacerItem7 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - self.verticalLayout_14.addItem(spacerItem7) - self.led_fic = QtGui.QLabel(self.tab_reception) - self.led_fic.setObjectName(_fromUtf8("led_fic")) - self.verticalLayout_14.addWidget(self.led_fic) - spacerItem8 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - self.verticalLayout_14.addItem(spacerItem8) - self.horizontalLayout_32.addLayout(self.verticalLayout_14) - self.label_label_fic = QtGui.QLabel(self.tab_reception) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.label_label_fic.setFont(font) - self.label_label_fic.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.label_label_fic.setObjectName(_fromUtf8("label_label_fic")) - self.horizontalLayout_32.addWidget(self.label_label_fic) - spacerItem9 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.horizontalLayout_32.addItem(spacerItem9) - self.vertical_layout_dev_mode_right_vertical.addLayout(self.horizontalLayout_32) - self.verticalLayout_7.addLayout(self.vertical_layout_dev_mode_right_vertical) - spacerItem10 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - self.verticalLayout_7.addItem(spacerItem10) - self.line_6 = QtGui.QFrame(self.tab_reception) - self.line_6.setFrameShape(QtGui.QFrame.HLine) - self.line_6.setFrameShadow(QtGui.QFrame.Sunken) - self.line_6.setObjectName(_fromUtf8("line_6")) - self.verticalLayout_7.addWidget(self.line_6) - self.horizontalLayout_24 = QtGui.QHBoxLayout() - self.horizontalLayout_24.setObjectName(_fromUtf8("horizontalLayout_24")) - self.label_service = QtGui.QLabel(self.tab_reception) - font = QtGui.QFont() - font.setPointSize(24) - self.label_service.setFont(font) - self.label_service.setAlignment(QtCore.Qt.AlignCenter) - self.label_service.setObjectName(_fromUtf8("label_service")) - self.horizontalLayout_24.addWidget(self.label_service) - self.verticalLayout_7.addLayout(self.horizontalLayout_24) - self.label_programme_type = QtGui.QLabel(self.tab_reception) - font = QtGui.QFont() - font.setPointSize(12) - self.label_programme_type.setFont(font) - self.label_programme_type.setAlignment(QtCore.Qt.AlignCenter) - self.label_programme_type.setObjectName(_fromUtf8("label_programme_type")) - self.verticalLayout_7.addWidget(self.label_programme_type) - self.horizontalLayout_25 = QtGui.QHBoxLayout() - self.horizontalLayout_25.setObjectName(_fromUtf8("horizontalLayout_25")) - self.label_bit_rate = QtGui.QLabel(self.tab_reception) - self.label_bit_rate.setAlignment(QtCore.Qt.AlignCenter) - self.label_bit_rate.setObjectName(_fromUtf8("label_bit_rate")) - self.horizontalLayout_25.addWidget(self.label_bit_rate) - self.label_primary = QtGui.QLabel(self.tab_reception) - self.label_primary.setAlignment(QtCore.Qt.AlignCenter) - self.label_primary.setObjectName(_fromUtf8("label_primary")) - self.horizontalLayout_25.addWidget(self.label_primary) - self.label_dabplus = QtGui.QLabel(self.tab_reception) - self.label_dabplus.setAlignment(QtCore.Qt.AlignCenter) - self.label_dabplus.setObjectName(_fromUtf8("label_dabplus")) - self.horizontalLayout_25.addWidget(self.label_dabplus) - self.verticalLayout_7.addLayout(self.horizontalLayout_25) - self.line_7 = QtGui.QFrame(self.tab_reception) - self.line_7.setFrameShape(QtGui.QFrame.HLine) - self.line_7.setFrameShadow(QtGui.QFrame.Sunken) - self.line_7.setObjectName(_fromUtf8("line_7")) - self.verticalLayout_7.addWidget(self.line_7) - self.horizontalLayout_26 = QtGui.QHBoxLayout() - self.horizontalLayout_26.setObjectName(_fromUtf8("horizontalLayout_26")) - self.btn_init = QtGui.QPushButton(self.tab_reception) - font = QtGui.QFont() - font.setKerning(True) - self.btn_init.setFont(font) - icon = QtGui.QIcon.fromTheme(_fromUtf8("network-receive")) - self.btn_init.setIcon(icon) - self.btn_init.setCheckable(False) - self.btn_init.setFlat(False) - self.btn_init.setObjectName(_fromUtf8("btn_init")) - self.horizontalLayout_26.addWidget(self.btn_init) - self.btn_update_info = QtGui.QPushButton(self.tab_reception) - self.btn_update_info.setEnabled(False) - icon = QtGui.QIcon.fromTheme(_fromUtf8("system-search")) - self.btn_update_info.setIcon(icon) - self.btn_update_info.setObjectName(_fromUtf8("btn_update_info")) - self.horizontalLayout_26.addWidget(self.btn_update_info) - self.verticalLayout_7.addLayout(self.horizontalLayout_26) - self.line_9 = QtGui.QFrame(self.tab_reception) - self.line_9.setFrameShape(QtGui.QFrame.HLine) - self.line_9.setFrameShadow(QtGui.QFrame.Sunken) - self.line_9.setObjectName(_fromUtf8("line_9")) - self.verticalLayout_7.addWidget(self.line_9) - spacerItem11 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - self.verticalLayout_7.addItem(spacerItem11) - self.label_2 = QtGui.QLabel(self.tab_reception) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.label_2.setFont(font) - self.label_2.setLayoutDirection(QtCore.Qt.LeftToRight) - self.label_2.setObjectName(_fromUtf8("label_2")) - self.verticalLayout_7.addWidget(self.label_2) - self.horizontalLayout_5 = QtGui.QHBoxLayout() - self.horizontalLayout_5.setObjectName(_fromUtf8("horizontalLayout_5")) - self.btn_play = QtGui.QPushButton(self.tab_reception) - self.btn_play.setEnabled(False) - icon = QtGui.QIcon.fromTheme(_fromUtf8("media-playback-start")) - self.btn_play.setIcon(icon) - self.btn_play.setObjectName(_fromUtf8("btn_play")) - self.horizontalLayout_5.addWidget(self.btn_play) - self.btn_stop = QtGui.QPushButton(self.tab_reception) - self.btn_stop.setEnabled(True) - icon = QtGui.QIcon.fromTheme(_fromUtf8("media-playback-stop")) - self.btn_stop.setIcon(icon) - self.btn_stop.setObjectName(_fromUtf8("btn_stop")) - self.horizontalLayout_5.addWidget(self.btn_stop) - self.btn_record = QtGui.QPushButton(self.tab_reception) - self.btn_record.setEnabled(False) - icon = QtGui.QIcon.fromTheme(_fromUtf8("media-record")) - self.btn_record.setIcon(icon) - self.btn_record.setObjectName(_fromUtf8("btn_record")) - self.horizontalLayout_5.addWidget(self.btn_record) - self.verticalLayout_7.addLayout(self.horizontalLayout_5) - self.horizontalLayout_4 = QtGui.QHBoxLayout() - self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4")) - self.label_3 = QtGui.QLabel(self.tab_reception) - self.label_3.setObjectName(_fromUtf8("label_3")) - self.horizontalLayout_4.addWidget(self.label_3) - self.slider_volume = QtGui.QSlider(self.tab_reception) - self.slider_volume.setEnabled(False) - self.slider_volume.setMaximum(100) - self.slider_volume.setProperty("value", 80) - self.slider_volume.setSliderPosition(80) - self.slider_volume.setOrientation(QtCore.Qt.Horizontal) - self.slider_volume.setObjectName(_fromUtf8("slider_volume")) - self.horizontalLayout_4.addWidget(self.slider_volume) - self.verticalLayout_7.addLayout(self.horizontalLayout_4) - self.horizontal_layout_reception.addLayout(self.verticalLayout_7) - self.line_12 = QtGui.QFrame(self.tab_reception) - self.line_12.setFrameShape(QtGui.QFrame.VLine) - self.line_12.setFrameShadow(QtGui.QFrame.Sunken) - self.line_12.setObjectName(_fromUtf8("line_12")) - self.horizontal_layout_reception.addWidget(self.line_12) - self.dev_scroll_area = QtGui.QScrollArea(self.tab_reception) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.dev_scroll_area.sizePolicy().hasHeightForWidth()) - self.dev_scroll_area.setSizePolicy(sizePolicy) - self.dev_scroll_area.setMinimumSize(QtCore.QSize(0, 0)) - self.dev_scroll_area.setMaximumSize(QtCore.QSize(16777215, 16777215)) - self.dev_scroll_area.setWidgetResizable(True) - self.dev_scroll_area.setObjectName(_fromUtf8("dev_scroll_area")) - self.dev_scroll_area_content = QtGui.QWidget() - self.dev_scroll_area_content.setGeometry(QtCore.QRect(0, 0, 239, 602)) - self.dev_scroll_area_content.setObjectName(_fromUtf8("dev_scroll_area_content")) - self.verticalLayout_12 = QtGui.QVBoxLayout(self.dev_scroll_area_content) - self.verticalLayout_12.setObjectName(_fromUtf8("verticalLayout_12")) - self.vertical_layout_dev_mode_right = QtGui.QVBoxLayout() - self.vertical_layout_dev_mode_right.setObjectName(_fromUtf8("vertical_layout_dev_mode_right")) - self.verticalLayout_12.addLayout(self.vertical_layout_dev_mode_right) - self.dev_scroll_area.setWidget(self.dev_scroll_area_content) - self.horizontal_layout_reception.addWidget(self.dev_scroll_area) - self.verticalLayout_2.addLayout(self.horizontal_layout_reception) - self.mode_tabs.addTab(self.tab_reception, _fromUtf8("")) - self.tab_transmission = QtGui.QWidget() - self.tab_transmission.setObjectName(_fromUtf8("tab_transmission")) - self.verticalLayout_3 = QtGui.QVBoxLayout(self.tab_transmission) - self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) - self.horizontalLayout_7 = QtGui.QHBoxLayout() - self.horizontalLayout_7.setObjectName(_fromUtf8("horizontalLayout_7")) - self.verticalLayout_5 = QtGui.QVBoxLayout() - self.verticalLayout_5.setObjectName(_fromUtf8("verticalLayout_5")) - self.horizontalLayout_9 = QtGui.QHBoxLayout() - self.horizontalLayout_9.setObjectName(_fromUtf8("horizontalLayout_9")) - self.t_rbtn_USRP = QtGui.QRadioButton(self.tab_transmission) - self.t_rbtn_USRP.setEnabled(True) - self.t_rbtn_USRP.setChecked(True) - self.t_rbtn_USRP.setObjectName(_fromUtf8("t_rbtn_USRP")) - self.horizontalLayout_9.addWidget(self.t_rbtn_USRP) - spacerItem12 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.horizontalLayout_9.addItem(spacerItem12) - self.t_label_frequency = QtGui.QLabel(self.tab_transmission) - self.t_label_frequency.setObjectName(_fromUtf8("t_label_frequency")) - self.horizontalLayout_9.addWidget(self.t_label_frequency) - self.t_spinbox_frequency = QtGui.QSpinBox(self.tab_transmission) - self.t_spinbox_frequency.setMaximum(1000000000) - self.t_spinbox_frequency.setProperty("value", 208064000) - self.t_spinbox_frequency.setObjectName(_fromUtf8("t_spinbox_frequency")) - self.horizontalLayout_9.addWidget(self.t_spinbox_frequency) - self.label = QtGui.QLabel(self.tab_transmission) - self.label.setObjectName(_fromUtf8("label")) - self.horizontalLayout_9.addWidget(self.label) - self.verticalLayout_5.addLayout(self.horizontalLayout_9) - self.horizontalLayout_10 = QtGui.QHBoxLayout() - self.horizontalLayout_10.setObjectName(_fromUtf8("horizontalLayout_10")) - self.t_rbtn_File = QtGui.QRadioButton(self.tab_transmission) - self.t_rbtn_File.setObjectName(_fromUtf8("t_rbtn_File")) - self.horizontalLayout_10.addWidget(self.t_rbtn_File) - self.t_edit_file_name = QtGui.QLineEdit(self.tab_transmission) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.t_edit_file_name.sizePolicy().hasHeightForWidth()) - self.t_edit_file_name.setSizePolicy(sizePolicy) - self.t_edit_file_name.setObjectName(_fromUtf8("t_edit_file_name")) - self.horizontalLayout_10.addWidget(self.t_edit_file_name) - self.t_label_sink = QtGui.QLabel(self.tab_transmission) - self.t_label_sink.setEnabled(False) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.t_label_sink.sizePolicy().hasHeightForWidth()) - self.t_label_sink.setSizePolicy(sizePolicy) - self.t_label_sink.setMinimumSize(QtCore.QSize(100, 0)) - self.t_label_sink.setMaximumSize(QtCore.QSize(16777215, 16777215)) - self.t_label_sink.setFrameShape(QtGui.QFrame.Box) - self.t_label_sink.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.t_label_sink.setObjectName(_fromUtf8("t_label_sink")) - self.horizontalLayout_10.addWidget(self.t_label_sink) - self.t_btn_file_path = QtGui.QToolButton(self.tab_transmission) - self.t_btn_file_path.setEnabled(False) - self.t_btn_file_path.setObjectName(_fromUtf8("t_btn_file_path")) - self.horizontalLayout_10.addWidget(self.t_btn_file_path) - self.verticalLayout_5.addLayout(self.horizontalLayout_10) - self.horizontalLayout_31 = QtGui.QHBoxLayout() - self.horizontalLayout_31.setObjectName(_fromUtf8("horizontalLayout_31")) - spacerItem13 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.horizontalLayout_31.addItem(spacerItem13) - self.label_8 = QtGui.QLabel(self.tab_transmission) - self.label_8.setObjectName(_fromUtf8("label_8")) - self.horizontalLayout_31.addWidget(self.label_8) - self.t_spin_dab_mode = QtGui.QSpinBox(self.tab_transmission) - self.t_spin_dab_mode.setMinimum(1) - self.t_spin_dab_mode.setMaximum(4) - self.t_spin_dab_mode.setObjectName(_fromUtf8("t_spin_dab_mode")) - self.horizontalLayout_31.addWidget(self.t_spin_dab_mode) - self.verticalLayout_5.addLayout(self.horizontalLayout_31) - self.line_4 = QtGui.QFrame(self.tab_transmission) - self.line_4.setFrameShape(QtGui.QFrame.HLine) - self.line_4.setFrameShadow(QtGui.QFrame.Sunken) - self.line_4.setObjectName(_fromUtf8("line_4")) - self.verticalLayout_5.addWidget(self.line_4) - self.scrollArea = QtGui.QScrollArea(self.tab_transmission) - self.scrollArea.setWidgetResizable(True) - self.scrollArea.setObjectName(_fromUtf8("scrollArea")) - self.scrollAreaWidgetContents = QtGui.QWidget() - self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, -1028, 525, 1514)) - self.scrollAreaWidgetContents.setObjectName(_fromUtf8("scrollAreaWidgetContents")) - self.verticalLayout_9 = QtGui.QVBoxLayout(self.scrollAreaWidgetContents) - self.verticalLayout_9.setObjectName(_fromUtf8("verticalLayout_9")) - self.verticalLayout_4 = QtGui.QVBoxLayout() - self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4")) - self.formLayout_3 = QtGui.QFormLayout() - self.formLayout_3.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow) - self.formLayout_3.setObjectName(_fromUtf8("formLayout_3")) - self.line_2 = QtGui.QFrame(self.scrollAreaWidgetContents) - self.line_2.setFrameShape(QtGui.QFrame.HLine) - self.line_2.setFrameShadow(QtGui.QFrame.Sunken) - self.line_2.setObjectName(_fromUtf8("line_2")) - self.formLayout_3.setWidget(0, QtGui.QFormLayout.LabelRole, self.line_2) - self.t_label_heading_service_comp = QtGui.QLabel(self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(15) - font.setBold(True) - font.setWeight(75) - self.t_label_heading_service_comp.setFont(font) - self.t_label_heading_service_comp.setObjectName(_fromUtf8("t_label_heading_service_comp")) - self.formLayout_3.setWidget(1, QtGui.QFormLayout.LabelRole, self.t_label_heading_service_comp) - self.t_label_comp1 = QtGui.QLabel(self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(13) - font.setBold(True) - font.setWeight(75) - self.t_label_comp1.setFont(font) - self.t_label_comp1.setObjectName(_fromUtf8("t_label_comp1")) - self.formLayout_3.setWidget(2, QtGui.QFormLayout.LabelRole, self.t_label_comp1) - self.t_label_rate1 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_rate1.setObjectName(_fromUtf8("t_label_rate1")) - self.formLayout_3.setWidget(4, QtGui.QFormLayout.LabelRole, self.t_label_rate1) - self.t_spin_rate1 = QtGui.QSpinBox(self.scrollAreaWidgetContents) - self.t_spin_rate1.setMaximum(999) - self.t_spin_rate1.setProperty("value", 112) - self.t_spin_rate1.setObjectName(_fromUtf8("t_spin_rate1")) - self.formLayout_3.setWidget(4, QtGui.QFormLayout.FieldRole, self.t_spin_rate1) - self.t_label_prot1 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_prot1.setObjectName(_fromUtf8("t_label_prot1")) - self.formLayout_3.setWidget(5, QtGui.QFormLayout.LabelRole, self.t_label_prot1) - self.t_label_comp_src1 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_comp_src1.setObjectName(_fromUtf8("t_label_comp_src1")) - self.formLayout_3.setWidget(7, QtGui.QFormLayout.LabelRole, self.t_label_comp_src1) - self.horizontalLayout_13 = QtGui.QHBoxLayout() - self.horizontalLayout_13.setObjectName(_fromUtf8("horizontalLayout_13")) - self.t_btn_record1 = QtGui.QPushButton(self.scrollAreaWidgetContents) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.t_btn_record1.sizePolicy().hasHeightForWidth()) - self.t_btn_record1.setSizePolicy(sizePolicy) - self.t_btn_record1.setMinimumSize(QtCore.QSize(27, 27)) - self.t_btn_record1.setMaximumSize(QtCore.QSize(27, 27)) - self.t_btn_record1.setText(_fromUtf8("")) - icon = QtGui.QIcon.fromTheme(_fromUtf8("media-record")) - self.t_btn_record1.setIcon(icon) - self.t_btn_record1.setDefault(False) - self.t_btn_record1.setFlat(False) - self.t_btn_record1.setObjectName(_fromUtf8("t_btn_record1")) - self.horizontalLayout_13.addWidget(self.t_btn_record1) - self.t_label_path_src1 = QtGui.QLabel(self.scrollAreaWidgetContents) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.t_label_path_src1.sizePolicy().hasHeightForWidth()) - self.t_label_path_src1.setSizePolicy(sizePolicy) - self.t_label_path_src1.setMinimumSize(QtCore.QSize(100, 0)) - font = QtGui.QFont() - font.setUnderline(False) - font.setStrikeOut(False) - self.t_label_path_src1.setFont(font) - self.t_label_path_src1.setAutoFillBackground(False) - self.t_label_path_src1.setFrameShape(QtGui.QFrame.Box) - self.t_label_path_src1.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.t_label_path_src1.setObjectName(_fromUtf8("t_label_path_src1")) - self.horizontalLayout_13.addWidget(self.t_label_path_src1) - self.t_btn_path_src1 = QtGui.QToolButton(self.scrollAreaWidgetContents) - self.t_btn_path_src1.setObjectName(_fromUtf8("t_btn_path_src1")) - self.horizontalLayout_13.addWidget(self.t_btn_path_src1) - self.formLayout_3.setLayout(7, QtGui.QFormLayout.FieldRole, self.horizontalLayout_13) - self.t_label_comp2 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_comp2.setEnabled(True) - font = QtGui.QFont() - font.setPointSize(13) - font.setBold(True) - font.setWeight(75) - self.t_label_comp2.setFont(font) - self.t_label_comp2.setObjectName(_fromUtf8("t_label_comp2")) - self.formLayout_3.setWidget(8, QtGui.QFormLayout.LabelRole, self.t_label_comp2) - self.t_label_rate2 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_rate2.setObjectName(_fromUtf8("t_label_rate2")) - self.formLayout_3.setWidget(10, QtGui.QFormLayout.LabelRole, self.t_label_rate2) - self.t_spin_rate2 = QtGui.QSpinBox(self.scrollAreaWidgetContents) - self.t_spin_rate2.setMaximum(999) - self.t_spin_rate2.setProperty("value", 112) - self.t_spin_rate2.setObjectName(_fromUtf8("t_spin_rate2")) - self.formLayout_3.setWidget(10, QtGui.QFormLayout.FieldRole, self.t_spin_rate2) - self.t_label_prot2 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_prot2.setObjectName(_fromUtf8("t_label_prot2")) - self.formLayout_3.setWidget(11, QtGui.QFormLayout.LabelRole, self.t_label_prot2) - self.t_label_comp_src2 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_comp_src2.setObjectName(_fromUtf8("t_label_comp_src2")) - self.formLayout_3.setWidget(13, QtGui.QFormLayout.LabelRole, self.t_label_comp_src2) - self.horizontalLayout_14 = QtGui.QHBoxLayout() - self.horizontalLayout_14.setObjectName(_fromUtf8("horizontalLayout_14")) - self.t_btn_record2 = QtGui.QPushButton(self.scrollAreaWidgetContents) - self.t_btn_record2.setMaximumSize(QtCore.QSize(27, 27)) - self.t_btn_record2.setText(_fromUtf8("")) - icon = QtGui.QIcon.fromTheme(_fromUtf8("media-record")) - self.t_btn_record2.setIcon(icon) - self.t_btn_record2.setObjectName(_fromUtf8("t_btn_record2")) - self.horizontalLayout_14.addWidget(self.t_btn_record2) - self.t_label_path_src2 = QtGui.QLabel(self.scrollAreaWidgetContents) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.t_label_path_src2.sizePolicy().hasHeightForWidth()) - self.t_label_path_src2.setSizePolicy(sizePolicy) - self.t_label_path_src2.setMinimumSize(QtCore.QSize(100, 0)) - self.t_label_path_src2.setFrameShape(QtGui.QFrame.Box) - self.t_label_path_src2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.t_label_path_src2.setObjectName(_fromUtf8("t_label_path_src2")) - self.horizontalLayout_14.addWidget(self.t_label_path_src2) - self.t_btn_path_src2 = QtGui.QToolButton(self.scrollAreaWidgetContents) - self.t_btn_path_src2.setObjectName(_fromUtf8("t_btn_path_src2")) - self.horizontalLayout_14.addWidget(self.t_btn_path_src2) - self.formLayout_3.setLayout(13, QtGui.QFormLayout.FieldRole, self.horizontalLayout_14) - self.t_label_comp3 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_comp3.setEnabled(True) - font = QtGui.QFont() - font.setPointSize(13) - font.setBold(True) - font.setWeight(75) - self.t_label_comp3.setFont(font) - self.t_label_comp3.setObjectName(_fromUtf8("t_label_comp3")) - self.formLayout_3.setWidget(14, QtGui.QFormLayout.LabelRole, self.t_label_comp3) - self.t_label_rate3 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_rate3.setObjectName(_fromUtf8("t_label_rate3")) - self.formLayout_3.setWidget(16, QtGui.QFormLayout.LabelRole, self.t_label_rate3) - self.t_spin_rate3 = QtGui.QSpinBox(self.scrollAreaWidgetContents) - self.t_spin_rate3.setMaximum(999) - self.t_spin_rate3.setProperty("value", 112) - self.t_spin_rate3.setObjectName(_fromUtf8("t_spin_rate3")) - self.formLayout_3.setWidget(16, QtGui.QFormLayout.FieldRole, self.t_spin_rate3) - self.t_label_prot3 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_prot3.setObjectName(_fromUtf8("t_label_prot3")) - self.formLayout_3.setWidget(17, QtGui.QFormLayout.LabelRole, self.t_label_prot3) - self.t_label_comp_src3 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_comp_src3.setObjectName(_fromUtf8("t_label_comp_src3")) - self.formLayout_3.setWidget(19, QtGui.QFormLayout.LabelRole, self.t_label_comp_src3) - self.horizontalLayout_15 = QtGui.QHBoxLayout() - self.horizontalLayout_15.setObjectName(_fromUtf8("horizontalLayout_15")) - self.t_btn_record3 = QtGui.QPushButton(self.scrollAreaWidgetContents) - self.t_btn_record3.setMaximumSize(QtCore.QSize(27, 27)) - self.t_btn_record3.setText(_fromUtf8("")) - icon = QtGui.QIcon.fromTheme(_fromUtf8("media-record")) - self.t_btn_record3.setIcon(icon) - self.t_btn_record3.setObjectName(_fromUtf8("t_btn_record3")) - self.horizontalLayout_15.addWidget(self.t_btn_record3) - self.t_label_path_src3 = QtGui.QLabel(self.scrollAreaWidgetContents) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.t_label_path_src3.sizePolicy().hasHeightForWidth()) - self.t_label_path_src3.setSizePolicy(sizePolicy) - self.t_label_path_src3.setMinimumSize(QtCore.QSize(100, 0)) - self.t_label_path_src3.setFrameShape(QtGui.QFrame.Box) - self.t_label_path_src3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.t_label_path_src3.setObjectName(_fromUtf8("t_label_path_src3")) - self.horizontalLayout_15.addWidget(self.t_label_path_src3) - self.t_btn_path_src3 = QtGui.QToolButton(self.scrollAreaWidgetContents) - self.t_btn_path_src3.setObjectName(_fromUtf8("t_btn_path_src3")) - self.horizontalLayout_15.addWidget(self.t_btn_path_src3) - self.formLayout_3.setLayout(19, QtGui.QFormLayout.FieldRole, self.horizontalLayout_15) - self.t_label_comp4 = QtGui.QLabel(self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(13) - font.setBold(True) - font.setWeight(75) - self.t_label_comp4.setFont(font) - self.t_label_comp4.setObjectName(_fromUtf8("t_label_comp4")) - self.formLayout_3.setWidget(20, QtGui.QFormLayout.LabelRole, self.t_label_comp4) - self.t_label_rate4 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_rate4.setObjectName(_fromUtf8("t_label_rate4")) - self.formLayout_3.setWidget(22, QtGui.QFormLayout.LabelRole, self.t_label_rate4) - self.t_spin_rate4 = QtGui.QSpinBox(self.scrollAreaWidgetContents) - self.t_spin_rate4.setMaximum(999) - self.t_spin_rate4.setProperty("value", 112) - self.t_spin_rate4.setObjectName(_fromUtf8("t_spin_rate4")) - self.formLayout_3.setWidget(22, QtGui.QFormLayout.FieldRole, self.t_spin_rate4) - self.t_label_prot4 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_prot4.setObjectName(_fromUtf8("t_label_prot4")) - self.formLayout_3.setWidget(23, QtGui.QFormLayout.LabelRole, self.t_label_prot4) - self.t_label_comp_src4 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_comp_src4.setObjectName(_fromUtf8("t_label_comp_src4")) - self.formLayout_3.setWidget(25, QtGui.QFormLayout.LabelRole, self.t_label_comp_src4) - self.horizontalLayout_16 = QtGui.QHBoxLayout() - self.horizontalLayout_16.setObjectName(_fromUtf8("horizontalLayout_16")) - self.t_btn_record4 = QtGui.QPushButton(self.scrollAreaWidgetContents) - self.t_btn_record4.setMaximumSize(QtCore.QSize(27, 27)) - self.t_btn_record4.setText(_fromUtf8("")) - icon = QtGui.QIcon.fromTheme(_fromUtf8("media-record")) - self.t_btn_record4.setIcon(icon) - self.t_btn_record4.setObjectName(_fromUtf8("t_btn_record4")) - self.horizontalLayout_16.addWidget(self.t_btn_record4) - self.t_label_path_src4 = QtGui.QLabel(self.scrollAreaWidgetContents) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.t_label_path_src4.sizePolicy().hasHeightForWidth()) - self.t_label_path_src4.setSizePolicy(sizePolicy) - self.t_label_path_src4.setMinimumSize(QtCore.QSize(100, 0)) - self.t_label_path_src4.setFrameShape(QtGui.QFrame.Box) - self.t_label_path_src4.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.t_label_path_src4.setObjectName(_fromUtf8("t_label_path_src4")) - self.horizontalLayout_16.addWidget(self.t_label_path_src4) - self.t_btn_path_src4 = QtGui.QToolButton(self.scrollAreaWidgetContents) - self.t_btn_path_src4.setObjectName(_fromUtf8("t_btn_path_src4")) - self.horizontalLayout_16.addWidget(self.t_btn_path_src4) - self.formLayout_3.setLayout(25, QtGui.QFormLayout.FieldRole, self.horizontalLayout_16) - self.t_label_comp5 = QtGui.QLabel(self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(13) - font.setBold(True) - font.setWeight(75) - self.t_label_comp5.setFont(font) - self.t_label_comp5.setObjectName(_fromUtf8("t_label_comp5")) - self.formLayout_3.setWidget(26, QtGui.QFormLayout.LabelRole, self.t_label_comp5) - self.t_label_rate5 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_rate5.setObjectName(_fromUtf8("t_label_rate5")) - self.formLayout_3.setWidget(28, QtGui.QFormLayout.LabelRole, self.t_label_rate5) - self.t_spin_rate5 = QtGui.QSpinBox(self.scrollAreaWidgetContents) - self.t_spin_rate5.setMaximum(999) - self.t_spin_rate5.setProperty("value", 112) - self.t_spin_rate5.setObjectName(_fromUtf8("t_spin_rate5")) - self.formLayout_3.setWidget(28, QtGui.QFormLayout.FieldRole, self.t_spin_rate5) - self.t_label_prot5 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_prot5.setObjectName(_fromUtf8("t_label_prot5")) - self.formLayout_3.setWidget(29, QtGui.QFormLayout.LabelRole, self.t_label_prot5) - self.t_label_comp_src5 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_comp_src5.setObjectName(_fromUtf8("t_label_comp_src5")) - self.formLayout_3.setWidget(31, QtGui.QFormLayout.LabelRole, self.t_label_comp_src5) - self.horizontalLayout_17 = QtGui.QHBoxLayout() - self.horizontalLayout_17.setObjectName(_fromUtf8("horizontalLayout_17")) - self.t_btn_record5 = QtGui.QPushButton(self.scrollAreaWidgetContents) - self.t_btn_record5.setMaximumSize(QtCore.QSize(27, 27)) - self.t_btn_record5.setText(_fromUtf8("")) - icon = QtGui.QIcon.fromTheme(_fromUtf8("media-record")) - self.t_btn_record5.setIcon(icon) - self.t_btn_record5.setObjectName(_fromUtf8("t_btn_record5")) - self.horizontalLayout_17.addWidget(self.t_btn_record5) - self.t_label_path_src5 = QtGui.QLabel(self.scrollAreaWidgetContents) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.t_label_path_src5.sizePolicy().hasHeightForWidth()) - self.t_label_path_src5.setSizePolicy(sizePolicy) - self.t_label_path_src5.setMinimumSize(QtCore.QSize(100, 0)) - self.t_label_path_src5.setFrameShape(QtGui.QFrame.Box) - self.t_label_path_src5.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.t_label_path_src5.setObjectName(_fromUtf8("t_label_path_src5")) - self.horizontalLayout_17.addWidget(self.t_label_path_src5) - self.t_btn_path_src5 = QtGui.QToolButton(self.scrollAreaWidgetContents) - self.t_btn_path_src5.setObjectName(_fromUtf8("t_btn_path_src5")) - self.horizontalLayout_17.addWidget(self.t_btn_path_src5) - self.formLayout_3.setLayout(31, QtGui.QFormLayout.FieldRole, self.horizontalLayout_17) - self.t_label_comp6 = QtGui.QLabel(self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(13) - font.setBold(True) - font.setWeight(75) - self.t_label_comp6.setFont(font) - self.t_label_comp6.setObjectName(_fromUtf8("t_label_comp6")) - self.formLayout_3.setWidget(32, QtGui.QFormLayout.LabelRole, self.t_label_comp6) - self.t_label_rate6 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_rate6.setObjectName(_fromUtf8("t_label_rate6")) - self.formLayout_3.setWidget(34, QtGui.QFormLayout.LabelRole, self.t_label_rate6) - self.t_spin_rate6 = QtGui.QSpinBox(self.scrollAreaWidgetContents) - self.t_spin_rate6.setMaximum(999) - self.t_spin_rate6.setProperty("value", 112) - self.t_spin_rate6.setObjectName(_fromUtf8("t_spin_rate6")) - self.formLayout_3.setWidget(34, QtGui.QFormLayout.FieldRole, self.t_spin_rate6) - self.t_label_prot6 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_prot6.setObjectName(_fromUtf8("t_label_prot6")) - self.formLayout_3.setWidget(35, QtGui.QFormLayout.LabelRole, self.t_label_prot6) - self.t_label_comp_src6 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_comp_src6.setObjectName(_fromUtf8("t_label_comp_src6")) - self.formLayout_3.setWidget(37, QtGui.QFormLayout.LabelRole, self.t_label_comp_src6) - self.horizontalLayout_18 = QtGui.QHBoxLayout() - self.horizontalLayout_18.setObjectName(_fromUtf8("horizontalLayout_18")) - self.t_btn_record6 = QtGui.QPushButton(self.scrollAreaWidgetContents) - self.t_btn_record6.setMaximumSize(QtCore.QSize(27, 27)) - self.t_btn_record6.setText(_fromUtf8("")) - icon = QtGui.QIcon.fromTheme(_fromUtf8("media-record")) - self.t_btn_record6.setIcon(icon) - self.t_btn_record6.setObjectName(_fromUtf8("t_btn_record6")) - self.horizontalLayout_18.addWidget(self.t_btn_record6) - self.t_label_path_src6 = QtGui.QLabel(self.scrollAreaWidgetContents) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.t_label_path_src6.sizePolicy().hasHeightForWidth()) - self.t_label_path_src6.setSizePolicy(sizePolicy) - self.t_label_path_src6.setMinimumSize(QtCore.QSize(100, 0)) - self.t_label_path_src6.setFrameShape(QtGui.QFrame.Box) - self.t_label_path_src6.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.t_label_path_src6.setObjectName(_fromUtf8("t_label_path_src6")) - self.horizontalLayout_18.addWidget(self.t_label_path_src6) - self.t_btn_path_src6 = QtGui.QToolButton(self.scrollAreaWidgetContents) - self.t_btn_path_src6.setObjectName(_fromUtf8("t_btn_path_src6")) - self.horizontalLayout_18.addWidget(self.t_btn_path_src6) - self.formLayout_3.setLayout(37, QtGui.QFormLayout.FieldRole, self.horizontalLayout_18) - self.t_label_comp7 = QtGui.QLabel(self.scrollAreaWidgetContents) - font = QtGui.QFont() - font.setPointSize(13) - font.setBold(True) - font.setWeight(75) - self.t_label_comp7.setFont(font) - self.t_label_comp7.setObjectName(_fromUtf8("t_label_comp7")) - self.formLayout_3.setWidget(38, QtGui.QFormLayout.LabelRole, self.t_label_comp7) - self.t_label_rate7 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_rate7.setObjectName(_fromUtf8("t_label_rate7")) - self.formLayout_3.setWidget(40, QtGui.QFormLayout.LabelRole, self.t_label_rate7) - self.t_spin_rate7 = QtGui.QSpinBox(self.scrollAreaWidgetContents) - self.t_spin_rate7.setMaximum(999) - self.t_spin_rate7.setProperty("value", 112) - self.t_spin_rate7.setObjectName(_fromUtf8("t_spin_rate7")) - self.formLayout_3.setWidget(40, QtGui.QFormLayout.FieldRole, self.t_spin_rate7) - self.t_label_prot7 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_prot7.setObjectName(_fromUtf8("t_label_prot7")) - self.formLayout_3.setWidget(41, QtGui.QFormLayout.LabelRole, self.t_label_prot7) - self.t_label_comp_src7 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_comp_src7.setObjectName(_fromUtf8("t_label_comp_src7")) - self.formLayout_3.setWidget(43, QtGui.QFormLayout.LabelRole, self.t_label_comp_src7) - self.horizontalLayout_19 = QtGui.QHBoxLayout() - self.horizontalLayout_19.setObjectName(_fromUtf8("horizontalLayout_19")) - self.t_btn_record7 = QtGui.QPushButton(self.scrollAreaWidgetContents) - self.t_btn_record7.setMaximumSize(QtCore.QSize(27, 27)) - self.t_btn_record7.setText(_fromUtf8("")) - icon = QtGui.QIcon.fromTheme(_fromUtf8("media-record")) - self.t_btn_record7.setIcon(icon) - self.t_btn_record7.setObjectName(_fromUtf8("t_btn_record7")) - self.horizontalLayout_19.addWidget(self.t_btn_record7) - self.t_label_path_src7 = QtGui.QLabel(self.scrollAreaWidgetContents) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.t_label_path_src7.sizePolicy().hasHeightForWidth()) - self.t_label_path_src7.setSizePolicy(sizePolicy) - self.t_label_path_src7.setMinimumSize(QtCore.QSize(100, 0)) - self.t_label_path_src7.setFrameShape(QtGui.QFrame.Box) - self.t_label_path_src7.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) - self.t_label_path_src7.setObjectName(_fromUtf8("t_label_path_src7")) - self.horizontalLayout_19.addWidget(self.t_label_path_src7) - self.t_btn_path_src7 = QtGui.QToolButton(self.scrollAreaWidgetContents) - self.t_btn_path_src7.setObjectName(_fromUtf8("t_btn_path_src7")) - self.horizontalLayout_19.addWidget(self.t_btn_path_src7) - self.formLayout_3.setLayout(43, QtGui.QFormLayout.FieldRole, self.horizontalLayout_19) - self.t_label_label1 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_label1.setObjectName(_fromUtf8("t_label_label1")) - self.formLayout_3.setWidget(3, QtGui.QFormLayout.LabelRole, self.t_label_label1) - self.t_label_label2 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_label2.setObjectName(_fromUtf8("t_label_label2")) - self.formLayout_3.setWidget(9, QtGui.QFormLayout.LabelRole, self.t_label_label2) - self.t_label_label3 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_label3.setObjectName(_fromUtf8("t_label_label3")) - self.formLayout_3.setWidget(15, QtGui.QFormLayout.LabelRole, self.t_label_label3) - self.t_label_label4 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_label4.setObjectName(_fromUtf8("t_label_label4")) - self.formLayout_3.setWidget(21, QtGui.QFormLayout.LabelRole, self.t_label_label4) - self.t_label_label5 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_label5.setObjectName(_fromUtf8("t_label_label5")) - self.formLayout_3.setWidget(27, QtGui.QFormLayout.LabelRole, self.t_label_label5) - self.t_label_label6 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_label6.setObjectName(_fromUtf8("t_label_label6")) - self.formLayout_3.setWidget(33, QtGui.QFormLayout.LabelRole, self.t_label_label6) - self.t_label_label7 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_label7.setObjectName(_fromUtf8("t_label_label7")) - self.formLayout_3.setWidget(39, QtGui.QFormLayout.LabelRole, self.t_label_label7) - self.t_edit_service_label1 = QtGui.QLineEdit(self.scrollAreaWidgetContents) - self.t_edit_service_label1.setObjectName(_fromUtf8("t_edit_service_label1")) - self.formLayout_3.setWidget(3, QtGui.QFormLayout.FieldRole, self.t_edit_service_label1) - self.t_edit_service_label2 = QtGui.QLineEdit(self.scrollAreaWidgetContents) - self.t_edit_service_label2.setObjectName(_fromUtf8("t_edit_service_label2")) - self.formLayout_3.setWidget(9, QtGui.QFormLayout.FieldRole, self.t_edit_service_label2) - self.t_edit_service_label3 = QtGui.QLineEdit(self.scrollAreaWidgetContents) - self.t_edit_service_label3.setObjectName(_fromUtf8("t_edit_service_label3")) - self.formLayout_3.setWidget(15, QtGui.QFormLayout.FieldRole, self.t_edit_service_label3) - self.t_edit_service_label4 = QtGui.QLineEdit(self.scrollAreaWidgetContents) - self.t_edit_service_label4.setObjectName(_fromUtf8("t_edit_service_label4")) - self.formLayout_3.setWidget(21, QtGui.QFormLayout.FieldRole, self.t_edit_service_label4) - self.t_edit_service_label5 = QtGui.QLineEdit(self.scrollAreaWidgetContents) - self.t_edit_service_label5.setObjectName(_fromUtf8("t_edit_service_label5")) - self.formLayout_3.setWidget(27, QtGui.QFormLayout.FieldRole, self.t_edit_service_label5) - self.t_edit_service_label6 = QtGui.QLineEdit(self.scrollAreaWidgetContents) - self.t_edit_service_label6.setObjectName(_fromUtf8("t_edit_service_label6")) - self.formLayout_3.setWidget(33, QtGui.QFormLayout.FieldRole, self.t_edit_service_label6) - self.t_edit_service_label7 = QtGui.QLineEdit(self.scrollAreaWidgetContents) - self.t_edit_service_label7.setObjectName(_fromUtf8("t_edit_service_label7")) - self.formLayout_3.setWidget(39, QtGui.QFormLayout.FieldRole, self.t_edit_service_label7) - self.t_layout_combo_dabplus1 = QtGui.QHBoxLayout() - self.t_layout_combo_dabplus1.setObjectName(_fromUtf8("t_layout_combo_dabplus1")) - spacerItem14 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.t_layout_combo_dabplus1.addItem(spacerItem14) - self.t_combo_dabplus1 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_dabplus1.setObjectName(_fromUtf8("t_combo_dabplus1")) - self.t_combo_dabplus1.addItem(_fromUtf8("")) - self.t_combo_dabplus1.addItem(_fromUtf8("")) - self.t_layout_combo_dabplus1.addWidget(self.t_combo_dabplus1) - self.formLayout_3.setLayout(2, QtGui.QFormLayout.FieldRole, self.t_layout_combo_dabplus1) - self.t_layout_combo_dabplus2 = QtGui.QHBoxLayout() - self.t_layout_combo_dabplus2.setObjectName(_fromUtf8("t_layout_combo_dabplus2")) - spacerItem15 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.t_layout_combo_dabplus2.addItem(spacerItem15) - self.t_combo_dabplus2 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_dabplus2.setObjectName(_fromUtf8("t_combo_dabplus2")) - self.t_combo_dabplus2.addItem(_fromUtf8("")) - self.t_combo_dabplus2.addItem(_fromUtf8("")) - self.t_layout_combo_dabplus2.addWidget(self.t_combo_dabplus2) - self.formLayout_3.setLayout(8, QtGui.QFormLayout.FieldRole, self.t_layout_combo_dabplus2) - self.t_layout_combo_dabplus3 = QtGui.QHBoxLayout() - self.t_layout_combo_dabplus3.setObjectName(_fromUtf8("t_layout_combo_dabplus3")) - spacerItem16 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.t_layout_combo_dabplus3.addItem(spacerItem16) - self.t_combo_dabplus3 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_dabplus3.setObjectName(_fromUtf8("t_combo_dabplus3")) - self.t_combo_dabplus3.addItem(_fromUtf8("")) - self.t_combo_dabplus3.addItem(_fromUtf8("")) - self.t_layout_combo_dabplus3.addWidget(self.t_combo_dabplus3) - self.formLayout_3.setLayout(14, QtGui.QFormLayout.FieldRole, self.t_layout_combo_dabplus3) - self.t_layout_combo_dabplus4 = QtGui.QHBoxLayout() - self.t_layout_combo_dabplus4.setObjectName(_fromUtf8("t_layout_combo_dabplus4")) - spacerItem17 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.t_layout_combo_dabplus4.addItem(spacerItem17) - self.t_combo_dabplus4 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_dabplus4.setObjectName(_fromUtf8("t_combo_dabplus4")) - self.t_combo_dabplus4.addItem(_fromUtf8("")) - self.t_combo_dabplus4.addItem(_fromUtf8("")) - self.t_layout_combo_dabplus4.addWidget(self.t_combo_dabplus4) - self.formLayout_3.setLayout(20, QtGui.QFormLayout.FieldRole, self.t_layout_combo_dabplus4) - self.t_layout_combo_dabplus5 = QtGui.QHBoxLayout() - self.t_layout_combo_dabplus5.setObjectName(_fromUtf8("t_layout_combo_dabplus5")) - spacerItem18 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.t_layout_combo_dabplus5.addItem(spacerItem18) - self.t_combo_dabplus5 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_dabplus5.setObjectName(_fromUtf8("t_combo_dabplus5")) - self.t_combo_dabplus5.addItem(_fromUtf8("")) - self.t_combo_dabplus5.addItem(_fromUtf8("")) - self.t_layout_combo_dabplus5.addWidget(self.t_combo_dabplus5) - self.formLayout_3.setLayout(26, QtGui.QFormLayout.FieldRole, self.t_layout_combo_dabplus5) - self.t_layout_combo_dabplus6 = QtGui.QHBoxLayout() - self.t_layout_combo_dabplus6.setObjectName(_fromUtf8("t_layout_combo_dabplus6")) - spacerItem19 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.t_layout_combo_dabplus6.addItem(spacerItem19) - self.t_combo_dabplus6 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_dabplus6.setObjectName(_fromUtf8("t_combo_dabplus6")) - self.t_combo_dabplus6.addItem(_fromUtf8("")) - self.t_combo_dabplus6.addItem(_fromUtf8("")) - self.t_layout_combo_dabplus6.addWidget(self.t_combo_dabplus6) - self.formLayout_3.setLayout(32, QtGui.QFormLayout.FieldRole, self.t_layout_combo_dabplus6) - self.t_layout_combo_dabplus7 = QtGui.QHBoxLayout() - self.t_layout_combo_dabplus7.setObjectName(_fromUtf8("t_layout_combo_dabplus7")) - spacerItem20 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.t_layout_combo_dabplus7.addItem(spacerItem20) - self.t_combo_dabplus7 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_dabplus7.setObjectName(_fromUtf8("t_combo_dabplus7")) - self.t_combo_dabplus7.addItem(_fromUtf8("")) - self.t_combo_dabplus7.addItem(_fromUtf8("")) - self.t_layout_combo_dabplus7.addWidget(self.t_combo_dabplus7) - self.formLayout_3.setLayout(38, QtGui.QFormLayout.FieldRole, self.t_layout_combo_dabplus7) - self.t_combo_prot1 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_prot1.setObjectName(_fromUtf8("t_combo_prot1")) - self.t_combo_prot1.addItem(_fromUtf8("")) - self.t_combo_prot1.addItem(_fromUtf8("")) - self.t_combo_prot1.addItem(_fromUtf8("")) - self.t_combo_prot1.addItem(_fromUtf8("")) - self.formLayout_3.setWidget(5, QtGui.QFormLayout.FieldRole, self.t_combo_prot1) - self.t_combo_prot2 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_prot2.setObjectName(_fromUtf8("t_combo_prot2")) - self.t_combo_prot2.addItem(_fromUtf8("")) - self.t_combo_prot2.addItem(_fromUtf8("")) - self.t_combo_prot2.addItem(_fromUtf8("")) - self.t_combo_prot2.addItem(_fromUtf8("")) - self.formLayout_3.setWidget(11, QtGui.QFormLayout.FieldRole, self.t_combo_prot2) - self.t_combo_prot3 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_prot3.setObjectName(_fromUtf8("t_combo_prot3")) - self.t_combo_prot3.addItem(_fromUtf8("")) - self.t_combo_prot3.addItem(_fromUtf8("")) - self.t_combo_prot3.addItem(_fromUtf8("")) - self.t_combo_prot3.addItem(_fromUtf8("")) - self.formLayout_3.setWidget(17, QtGui.QFormLayout.FieldRole, self.t_combo_prot3) - self.t_combo_prot4 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_prot4.setObjectName(_fromUtf8("t_combo_prot4")) - self.t_combo_prot4.addItem(_fromUtf8("")) - self.t_combo_prot4.addItem(_fromUtf8("")) - self.t_combo_prot4.addItem(_fromUtf8("")) - self.t_combo_prot4.addItem(_fromUtf8("")) - self.formLayout_3.setWidget(23, QtGui.QFormLayout.FieldRole, self.t_combo_prot4) - self.t_combo_prot5 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_prot5.setObjectName(_fromUtf8("t_combo_prot5")) - self.t_combo_prot5.addItem(_fromUtf8("")) - self.t_combo_prot5.addItem(_fromUtf8("")) - self.t_combo_prot5.addItem(_fromUtf8("")) - self.t_combo_prot5.addItem(_fromUtf8("")) - self.formLayout_3.setWidget(29, QtGui.QFormLayout.FieldRole, self.t_combo_prot5) - self.t_combo_prot6 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_prot6.setObjectName(_fromUtf8("t_combo_prot6")) - self.t_combo_prot6.addItem(_fromUtf8("")) - self.t_combo_prot6.addItem(_fromUtf8("")) - self.t_combo_prot6.addItem(_fromUtf8("")) - self.t_combo_prot6.addItem(_fromUtf8("")) - self.formLayout_3.setWidget(35, QtGui.QFormLayout.FieldRole, self.t_combo_prot6) - self.t_combo_prot7 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_prot7.setObjectName(_fromUtf8("t_combo_prot7")) - self.t_combo_prot7.addItem(_fromUtf8("")) - self.t_combo_prot7.addItem(_fromUtf8("")) - self.t_combo_prot7.addItem(_fromUtf8("")) - self.t_combo_prot7.addItem(_fromUtf8("")) - self.formLayout_3.setWidget(41, QtGui.QFormLayout.FieldRole, self.t_combo_prot7) - self.t_label_audio_rate1 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_audio_rate1.setObjectName(_fromUtf8("t_label_audio_rate1")) - self.formLayout_3.setWidget(6, QtGui.QFormLayout.LabelRole, self.t_label_audio_rate1) - self.t_label_audio_rate2 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_audio_rate2.setObjectName(_fromUtf8("t_label_audio_rate2")) - self.formLayout_3.setWidget(12, QtGui.QFormLayout.LabelRole, self.t_label_audio_rate2) - self.t_label_audio_rate3 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_audio_rate3.setObjectName(_fromUtf8("t_label_audio_rate3")) - self.formLayout_3.setWidget(18, QtGui.QFormLayout.LabelRole, self.t_label_audio_rate3) - self.t_label_audio_rate4 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_audio_rate4.setObjectName(_fromUtf8("t_label_audio_rate4")) - self.formLayout_3.setWidget(24, QtGui.QFormLayout.LabelRole, self.t_label_audio_rate4) - self.t_label_audio_rate5 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_audio_rate5.setObjectName(_fromUtf8("t_label_audio_rate5")) - self.formLayout_3.setWidget(30, QtGui.QFormLayout.LabelRole, self.t_label_audio_rate5) - self.t_label_audio_rate6 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_audio_rate6.setObjectName(_fromUtf8("t_label_audio_rate6")) - self.formLayout_3.setWidget(36, QtGui.QFormLayout.LabelRole, self.t_label_audio_rate6) - self.t_label_audio_rate7 = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_audio_rate7.setObjectName(_fromUtf8("t_label_audio_rate7")) - self.formLayout_3.setWidget(42, QtGui.QFormLayout.LabelRole, self.t_label_audio_rate7) - self.horizontalLayout_2 = QtGui.QHBoxLayout() - self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) - self.t_combo_stereo1 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_stereo1.setObjectName(_fromUtf8("t_combo_stereo1")) - self.t_combo_stereo1.addItem(_fromUtf8("")) - self.t_combo_stereo1.addItem(_fromUtf8("")) - self.horizontalLayout_2.addWidget(self.t_combo_stereo1) - self.t_combo_audio_rate1 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate1.setObjectName(_fromUtf8("t_combo_audio_rate1")) - self.t_combo_audio_rate1.addItem(_fromUtf8("")) - self.t_combo_audio_rate1.addItem(_fromUtf8("")) - self.horizontalLayout_2.addWidget(self.t_combo_audio_rate1) - self.t_combo_audio_rate_dab1 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate_dab1.setObjectName(_fromUtf8("t_combo_audio_rate_dab1")) - self.t_combo_audio_rate_dab1.addItem(_fromUtf8("")) - self.t_combo_audio_rate_dab1.addItem(_fromUtf8("")) - self.horizontalLayout_2.addWidget(self.t_combo_audio_rate_dab1) - self.formLayout_3.setLayout(6, QtGui.QFormLayout.FieldRole, self.horizontalLayout_2) - self.horizontalLayout_33 = QtGui.QHBoxLayout() - self.horizontalLayout_33.setObjectName(_fromUtf8("horizontalLayout_33")) - self.t_combo_stereo2 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_stereo2.setObjectName(_fromUtf8("t_combo_stereo2")) - self.t_combo_stereo2.addItem(_fromUtf8("")) - self.t_combo_stereo2.addItem(_fromUtf8("")) - self.horizontalLayout_33.addWidget(self.t_combo_stereo2) - self.t_combo_audio_rate2 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate2.setObjectName(_fromUtf8("t_combo_audio_rate2")) - self.t_combo_audio_rate2.addItem(_fromUtf8("")) - self.t_combo_audio_rate2.addItem(_fromUtf8("")) - self.horizontalLayout_33.addWidget(self.t_combo_audio_rate2) - self.t_combo_audio_rate_dab2 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate_dab2.setObjectName(_fromUtf8("t_combo_audio_rate_dab2")) - self.t_combo_audio_rate_dab2.addItem(_fromUtf8("")) - self.t_combo_audio_rate_dab2.addItem(_fromUtf8("")) - self.horizontalLayout_33.addWidget(self.t_combo_audio_rate_dab2) - self.formLayout_3.setLayout(12, QtGui.QFormLayout.FieldRole, self.horizontalLayout_33) - self.horizontalLayout_34 = QtGui.QHBoxLayout() - self.horizontalLayout_34.setObjectName(_fromUtf8("horizontalLayout_34")) - self.t_combo_stereo3 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_stereo3.setObjectName(_fromUtf8("t_combo_stereo3")) - self.t_combo_stereo3.addItem(_fromUtf8("")) - self.t_combo_stereo3.addItem(_fromUtf8("")) - self.horizontalLayout_34.addWidget(self.t_combo_stereo3) - self.t_combo_audio_rate3 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate3.setObjectName(_fromUtf8("t_combo_audio_rate3")) - self.t_combo_audio_rate3.addItem(_fromUtf8("")) - self.t_combo_audio_rate3.addItem(_fromUtf8("")) - self.horizontalLayout_34.addWidget(self.t_combo_audio_rate3) - self.t_combo_audio_rate_dab3 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate_dab3.setObjectName(_fromUtf8("t_combo_audio_rate_dab3")) - self.t_combo_audio_rate_dab3.addItem(_fromUtf8("")) - self.t_combo_audio_rate_dab3.addItem(_fromUtf8("")) - self.horizontalLayout_34.addWidget(self.t_combo_audio_rate_dab3) - self.formLayout_3.setLayout(18, QtGui.QFormLayout.FieldRole, self.horizontalLayout_34) - self.horizontalLayout_35 = QtGui.QHBoxLayout() - self.horizontalLayout_35.setObjectName(_fromUtf8("horizontalLayout_35")) - self.t_combo_stereo4 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_stereo4.setObjectName(_fromUtf8("t_combo_stereo4")) - self.t_combo_stereo4.addItem(_fromUtf8("")) - self.t_combo_stereo4.addItem(_fromUtf8("")) - self.horizontalLayout_35.addWidget(self.t_combo_stereo4) - self.t_combo_audio_rate4 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate4.setObjectName(_fromUtf8("t_combo_audio_rate4")) - self.t_combo_audio_rate4.addItem(_fromUtf8("")) - self.t_combo_audio_rate4.addItem(_fromUtf8("")) - self.horizontalLayout_35.addWidget(self.t_combo_audio_rate4) - self.t_combo_audio_rate_dab4 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate_dab4.setObjectName(_fromUtf8("t_combo_audio_rate_dab4")) - self.t_combo_audio_rate_dab4.addItem(_fromUtf8("")) - self.t_combo_audio_rate_dab4.addItem(_fromUtf8("")) - self.horizontalLayout_35.addWidget(self.t_combo_audio_rate_dab4) - self.formLayout_3.setLayout(24, QtGui.QFormLayout.FieldRole, self.horizontalLayout_35) - self.horizontalLayout_36 = QtGui.QHBoxLayout() - self.horizontalLayout_36.setObjectName(_fromUtf8("horizontalLayout_36")) - self.t_combo_stereo5 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_stereo5.setObjectName(_fromUtf8("t_combo_stereo5")) - self.t_combo_stereo5.addItem(_fromUtf8("")) - self.t_combo_stereo5.addItem(_fromUtf8("")) - self.horizontalLayout_36.addWidget(self.t_combo_stereo5) - self.t_combo_audio_rate5 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate5.setObjectName(_fromUtf8("t_combo_audio_rate5")) - self.t_combo_audio_rate5.addItem(_fromUtf8("")) - self.t_combo_audio_rate5.addItem(_fromUtf8("")) - self.horizontalLayout_36.addWidget(self.t_combo_audio_rate5) - self.t_combo_audio_rate_dab5 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate_dab5.setObjectName(_fromUtf8("t_combo_audio_rate_dab5")) - self.t_combo_audio_rate_dab5.addItem(_fromUtf8("")) - self.t_combo_audio_rate_dab5.addItem(_fromUtf8("")) - self.horizontalLayout_36.addWidget(self.t_combo_audio_rate_dab5) - self.formLayout_3.setLayout(30, QtGui.QFormLayout.FieldRole, self.horizontalLayout_36) - self.horizontalLayout_37 = QtGui.QHBoxLayout() - self.horizontalLayout_37.setObjectName(_fromUtf8("horizontalLayout_37")) - self.t_combo_stereo6 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_stereo6.setObjectName(_fromUtf8("t_combo_stereo6")) - self.t_combo_stereo6.addItem(_fromUtf8("")) - self.t_combo_stereo6.addItem(_fromUtf8("")) - self.horizontalLayout_37.addWidget(self.t_combo_stereo6) - self.t_combo_audio_rate6 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate6.setObjectName(_fromUtf8("t_combo_audio_rate6")) - self.t_combo_audio_rate6.addItem(_fromUtf8("")) - self.t_combo_audio_rate6.addItem(_fromUtf8("")) - self.horizontalLayout_37.addWidget(self.t_combo_audio_rate6) - self.t_combo_audio_rate_dab6 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate_dab6.setObjectName(_fromUtf8("t_combo_audio_rate_dab6")) - self.t_combo_audio_rate_dab6.addItem(_fromUtf8("")) - self.t_combo_audio_rate_dab6.addItem(_fromUtf8("")) - self.horizontalLayout_37.addWidget(self.t_combo_audio_rate_dab6) - self.formLayout_3.setLayout(36, QtGui.QFormLayout.FieldRole, self.horizontalLayout_37) - self.horizontalLayout_38 = QtGui.QHBoxLayout() - self.horizontalLayout_38.setObjectName(_fromUtf8("horizontalLayout_38")) - self.t_combo_stereo7 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_stereo7.setObjectName(_fromUtf8("t_combo_stereo7")) - self.t_combo_stereo7.addItem(_fromUtf8("")) - self.t_combo_stereo7.addItem(_fromUtf8("")) - self.horizontalLayout_38.addWidget(self.t_combo_stereo7) - self.t_combo_audio_rate7 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate7.setObjectName(_fromUtf8("t_combo_audio_rate7")) - self.t_combo_audio_rate7.addItem(_fromUtf8("")) - self.t_combo_audio_rate7.addItem(_fromUtf8("")) - self.horizontalLayout_38.addWidget(self.t_combo_audio_rate7) - self.t_combo_audio_rate_dab7 = QtGui.QComboBox(self.scrollAreaWidgetContents) - self.t_combo_audio_rate_dab7.setObjectName(_fromUtf8("t_combo_audio_rate_dab7")) - self.t_combo_audio_rate_dab7.addItem(_fromUtf8("")) - self.t_combo_audio_rate_dab7.addItem(_fromUtf8("")) - self.horizontalLayout_38.addWidget(self.t_combo_audio_rate_dab7) - self.formLayout_3.setLayout(42, QtGui.QFormLayout.FieldRole, self.horizontalLayout_38) - self.verticalLayout_4.addLayout(self.formLayout_3) - self.line_15 = QtGui.QFrame(self.scrollAreaWidgetContents) - self.line_15.setFrameShape(QtGui.QFrame.HLine) - self.line_15.setFrameShadow(QtGui.QFrame.Sunken) - self.line_15.setObjectName(_fromUtf8("line_15")) - self.verticalLayout_4.addWidget(self.line_15) - self.t_label_increase_num_subch_info = QtGui.QLabel(self.scrollAreaWidgetContents) - self.t_label_increase_num_subch_info.setEnabled(False) - font = QtGui.QFont() - font.setItalic(True) - font.setStrikeOut(False) - self.t_label_increase_num_subch_info.setFont(font) - self.t_label_increase_num_subch_info.setObjectName(_fromUtf8("t_label_increase_num_subch_info")) - self.verticalLayout_4.addWidget(self.t_label_increase_num_subch_info) - self.verticalLayout_9.addLayout(self.verticalLayout_4) - self.scrollArea.setWidget(self.scrollAreaWidgetContents) - self.verticalLayout_5.addWidget(self.scrollArea) - self.horizontalLayout_7.addLayout(self.verticalLayout_5) - self.line_3 = QtGui.QFrame(self.tab_transmission) - self.line_3.setFrameShape(QtGui.QFrame.VLine) - self.line_3.setFrameShadow(QtGui.QFrame.Sunken) - self.line_3.setObjectName(_fromUtf8("line_3")) - self.horizontalLayout_7.addWidget(self.line_3) - self.verticalLayout_8 = QtGui.QVBoxLayout() - self.verticalLayout_8.setObjectName(_fromUtf8("verticalLayout_8")) - self.line_5 = QtGui.QFrame(self.tab_transmission) - self.line_5.setFrameShape(QtGui.QFrame.HLine) - self.line_5.setFrameShadow(QtGui.QFrame.Sunken) - self.line_5.setObjectName(_fromUtf8("line_5")) - self.verticalLayout_8.addWidget(self.line_5) - self.formLayout_2 = QtGui.QFormLayout() - self.formLayout_2.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow) - self.formLayout_2.setObjectName(_fromUtf8("formLayout_2")) - self.label_12 = QtGui.QLabel(self.tab_transmission) - font = QtGui.QFont() - font.setPointSize(13) - font.setBold(True) - font.setWeight(75) - self.label_12.setFont(font) - self.label_12.setObjectName(_fromUtf8("label_12")) - self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.label_12) - self.label_13 = QtGui.QLabel(self.tab_transmission) - self.label_13.setObjectName(_fromUtf8("label_13")) - self.formLayout_2.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_13) - self.t_edit_ensemble_label = QtGui.QLineEdit(self.tab_transmission) - self.t_edit_ensemble_label.setObjectName(_fromUtf8("t_edit_ensemble_label")) - self.formLayout_2.setWidget(1, QtGui.QFormLayout.FieldRole, self.t_edit_ensemble_label) - self.label_14 = QtGui.QLabel(self.tab_transmission) - self.label_14.setObjectName(_fromUtf8("label_14")) - self.formLayout_2.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_14) - self.t_combo_country = QtGui.QComboBox(self.tab_transmission) - self.t_combo_country.setObjectName(_fromUtf8("t_combo_country")) - self.formLayout_2.setWidget(2, QtGui.QFormLayout.FieldRole, self.t_combo_country) - self.line = QtGui.QFrame(self.tab_transmission) - self.line.setFrameShape(QtGui.QFrame.HLine) - self.line.setFrameShadow(QtGui.QFrame.Sunken) - self.line.setObjectName(_fromUtf8("line")) - self.formLayout_2.setWidget(3, QtGui.QFormLayout.LabelRole, self.line) - self.label_17 = QtGui.QLabel(self.tab_transmission) - self.label_17.setObjectName(_fromUtf8("label_17")) - self.formLayout_2.setWidget(4, QtGui.QFormLayout.LabelRole, self.label_17) - self.t_spin_num_subch = QtGui.QSpinBox(self.tab_transmission) - self.t_spin_num_subch.setMaximum(4) - self.t_spin_num_subch.setProperty("value", 1) - self.t_spin_num_subch.setObjectName(_fromUtf8("t_spin_num_subch")) - self.formLayout_2.setWidget(4, QtGui.QFormLayout.FieldRole, self.t_spin_num_subch) - self.label_23 = QtGui.QLabel(self.tab_transmission) - self.label_23.setObjectName(_fromUtf8("label_23")) - self.formLayout_2.setWidget(5, QtGui.QFormLayout.LabelRole, self.label_23) - self.t_combo_language = QtGui.QComboBox(self.tab_transmission) - self.t_combo_language.setObjectName(_fromUtf8("t_combo_language")) - self.formLayout_2.setWidget(5, QtGui.QFormLayout.FieldRole, self.t_combo_language) - spacerItem21 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - self.formLayout_2.setItem(6, QtGui.QFormLayout.FieldRole, spacerItem21) - self.verticalLayout_8.addLayout(self.formLayout_2) - self.horizontalLayout_22 = QtGui.QHBoxLayout() - self.horizontalLayout_22.setObjectName(_fromUtf8("horizontalLayout_22")) - self.t_btn_init = QtGui.QPushButton(self.tab_transmission) - icon = QtGui.QIcon.fromTheme(_fromUtf8("network-transmit")) - self.t_btn_init.setIcon(icon) - self.t_btn_init.setObjectName(_fromUtf8("t_btn_init")) - self.horizontalLayout_22.addWidget(self.t_btn_init) - self.label_22 = QtGui.QLabel(self.tab_transmission) - self.label_22.setObjectName(_fromUtf8("label_22")) - self.horizontalLayout_22.addWidget(self.label_22) - self.t_label_status = QtGui.QLabel(self.tab_transmission) - self.t_label_status.setObjectName(_fromUtf8("t_label_status")) - self.horizontalLayout_22.addWidget(self.t_label_status) - spacerItem22 = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - self.horizontalLayout_22.addItem(spacerItem22) - self.verticalLayout_8.addLayout(self.horizontalLayout_22) - self.line_10 = QtGui.QFrame(self.tab_transmission) - self.line_10.setFrameShape(QtGui.QFrame.HLine) - self.line_10.setFrameShadow(QtGui.QFrame.Sunken) - self.line_10.setObjectName(_fromUtf8("line_10")) - self.verticalLayout_8.addWidget(self.line_10) - self.label_20 = QtGui.QLabel(self.tab_transmission) - font = QtGui.QFont() - font.setBold(True) - font.setWeight(75) - self.label_20.setFont(font) - self.label_20.setObjectName(_fromUtf8("label_20")) - self.verticalLayout_8.addWidget(self.label_20) - self.horizontalLayout_20 = QtGui.QHBoxLayout() - self.horizontalLayout_20.setObjectName(_fromUtf8("horizontalLayout_20")) - self.label_18 = QtGui.QLabel(self.tab_transmission) - self.label_18.setObjectName(_fromUtf8("label_18")) - self.horizontalLayout_20.addWidget(self.label_18) - self.t_spin_listen_to_component = QtGui.QSpinBox(self.tab_transmission) - self.t_spin_listen_to_component.setMinimum(1) - self.t_spin_listen_to_component.setMaximum(1) - self.t_spin_listen_to_component.setProperty("value", 1) - self.t_spin_listen_to_component.setObjectName(_fromUtf8("t_spin_listen_to_component")) - self.horizontalLayout_20.addWidget(self.t_spin_listen_to_component) - self.verticalLayout_8.addLayout(self.horizontalLayout_20) - self.horizontalLayout_11 = QtGui.QHBoxLayout() - self.horizontalLayout_11.setObjectName(_fromUtf8("horizontalLayout_11")) - self.t_btn_play = QtGui.QPushButton(self.tab_transmission) - self.t_btn_play.setEnabled(False) - icon = QtGui.QIcon.fromTheme(_fromUtf8("media-playback-start")) - self.t_btn_play.setIcon(icon) - self.t_btn_play.setObjectName(_fromUtf8("t_btn_play")) - self.horizontalLayout_11.addWidget(self.t_btn_play) - self.t_btn_stop = QtGui.QPushButton(self.tab_transmission) - self.t_btn_stop.setEnabled(False) - icon = QtGui.QIcon.fromTheme(_fromUtf8("media-playback-stop")) - self.t_btn_stop.setIcon(icon) - self.t_btn_stop.setObjectName(_fromUtf8("t_btn_stop")) - self.horizontalLayout_11.addWidget(self.t_btn_stop) - self.verticalLayout_8.addLayout(self.horizontalLayout_11) - self.horizontalLayout_12 = QtGui.QHBoxLayout() - self.horizontalLayout_12.setObjectName(_fromUtf8("horizontalLayout_12")) - self.label_19 = QtGui.QLabel(self.tab_transmission) - self.label_19.setEnabled(False) - self.label_19.setObjectName(_fromUtf8("label_19")) - self.horizontalLayout_12.addWidget(self.label_19) - self.t_slider_volume = QtGui.QSlider(self.tab_transmission) - self.t_slider_volume.setEnabled(False) - self.t_slider_volume.setMaximum(100) - self.t_slider_volume.setProperty("value", 80) - self.t_slider_volume.setOrientation(QtCore.Qt.Horizontal) - self.t_slider_volume.setObjectName(_fromUtf8("t_slider_volume")) - self.horizontalLayout_12.addWidget(self.t_slider_volume) - self.verticalLayout_8.addLayout(self.horizontalLayout_12) - self.horizontalLayout_7.addLayout(self.verticalLayout_8) - self.verticalLayout_3.addLayout(self.horizontalLayout_7) - self.mode_tabs.addTab(self.tab_transmission, _fromUtf8("")) - self.verticalLayout.addWidget(self.mode_tabs) - MainWindow.setCentralWidget(self.centralwidget) - self.statusBar = QtGui.QStatusBar(MainWindow) - self.statusBar.setAutoFillBackground(False) - self.statusBar.setObjectName(_fromUtf8("statusBar")) - MainWindow.setStatusBar(self.statusBar) - - self.retranslateUi(MainWindow) - self.mode_tabs.setCurrentIndex(0) - QtCore.QMetaObject.connectSlotsByName(MainWindow) - - def retranslateUi(self, MainWindow): - MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None)) - self.label_5.setText(_translate("MainWindow", "


", None)) - self.label_logo.setText(_translate("MainWindow", "

DABstep

", None)) - self.btn_dev_mode_close.setText(_translate("MainWindow", "Developer Mode", None)) - self.btn_dev_mode_open.setText(_translate("MainWindow", "Developer Mode", None)) - self.rbtn_USRP.setText(_translate("MainWindow", "USRP", None)) - self.label_frequency.setText(_translate("MainWindow", "Frequency", None)) - self.label_4.setText(_translate("MainWindow", "Hz ", None)) - self.rbtn_File.setText(_translate("MainWindow", "File", None)) - self.label_path.setText(_translate("MainWindow", "select path", None)) - self.btn_file_path.setText(_translate("MainWindow", "...", None)) - self.label_6.setText(_translate("MainWindow", "Transmission Mode", None)) - item = self.table_mci.horizontalHeaderItem(0) - item.setText(_translate("MainWindow", "ID", None)) - item = self.table_mci.horizontalHeaderItem(1) - item.setText(_translate("MainWindow", "Component", None)) - item = self.table_mci.horizontalHeaderItem(2) - item.setText(_translate("MainWindow", "Mode", None)) - item = self.table_mci.horizontalHeaderItem(3) - item.setText(_translate("MainWindow", "Type", None)) - self.label_ensemble.setText(_translate("MainWindow", "ENSEMBLE", None)) - self.label_26.setText(_translate("MainWindow", "services:", None)) - self.label_country.setText(_translate("MainWindow", "Country", None)) - self.label_snr.setText(_translate("MainWindow", "reception: ", None)) - self.label_7.setText(_translate("MainWindow", "dB", None)) - self.label_firecode.setText(_translate("MainWindow", "

Superframes:

", None)) - self.led_msc.setText(_translate("MainWindow", "led", None)) - self.label_label_msc.setText(_translate("MainWindow", "MSC", None)) - self.label_fic.setText(_translate("MainWindow", "

FIC:

", None)) - self.led_fic.setText(_translate("MainWindow", "led", None)) - self.label_label_fic.setText(_translate("MainWindow", "FIC", None)) - self.label_service.setText(_translate("MainWindow", "SERVICE", None)) - self.label_programme_type.setText(_translate("MainWindow", "programme type\n" -"", None)) - self.label_bit_rate.setText(_translate("MainWindow", "bit rate", None)) - self.label_primary.setText(_translate("MainWindow", "primary", None)) - self.label_dabplus.setText(_translate("MainWindow", "DAB", None)) - self.btn_init.setText(_translate("MainWindow", "start receiver", None)) - self.btn_update_info.setText(_translate("MainWindow", "scan ensemble", None)) - self.label_2.setText(_translate("MainWindow", "Audio Player", None)) - self.btn_play.setText(_translate("MainWindow", " Play", None)) - self.btn_stop.setText(_translate("MainWindow", " Stop", None)) - self.btn_record.setText(_translate("MainWindow", " Record", None)) - self.label_3.setText(_translate("MainWindow", "Volume", None)) - self.mode_tabs.setTabText(self.mode_tabs.indexOf(self.tab_reception), _translate("MainWindow", "Receiver", None)) - self.t_rbtn_USRP.setText(_translate("MainWindow", "USRP", None)) - self.t_label_frequency.setText(_translate("MainWindow", "Frequency", None)) - self.label.setText(_translate("MainWindow", "Hz ", None)) - self.t_rbtn_File.setText(_translate("MainWindow", "File", None)) - self.t_edit_file_name.setText(_translate("MainWindow", "gen_iq_dab.dat", None)) - self.t_label_sink.setText(_translate("MainWindow", "select path", None)) - self.t_btn_file_path.setText(_translate("MainWindow", "...", None)) - self.label_8.setText(_translate("MainWindow", "Transmission Mode", None)) - self.t_label_heading_service_comp.setText(_translate("MainWindow", "Service Components", None)) - self.t_label_comp1.setText(_translate("MainWindow", "Component 1", None)) - self.t_label_rate1.setText(_translate("MainWindow", "Data rate [kbit/s]", None)) - self.t_label_prot1.setText(_translate("MainWindow", "Protection Mode", None)) - self.t_label_comp_src1.setText(_translate("MainWindow", "Audio Source", None)) - self.t_label_path_src1.setText(_translate("MainWindow", "select audio", None)) - self.t_btn_path_src1.setText(_translate("MainWindow", "...", None)) - self.t_label_comp2.setText(_translate("MainWindow", "Component 2 ", None)) - self.t_label_rate2.setText(_translate("MainWindow", "Data rate [kbit/s]", None)) - self.t_label_prot2.setText(_translate("MainWindow", "Protection Mode", None)) - self.t_label_comp_src2.setText(_translate("MainWindow", "Audio Source", None)) - self.t_label_path_src2.setText(_translate("MainWindow", "select audio", None)) - self.t_btn_path_src2.setText(_translate("MainWindow", "...", None)) - self.t_label_comp3.setText(_translate("MainWindow", "Component 3", None)) - self.t_label_rate3.setText(_translate("MainWindow", "Data rate [kbit/s]", None)) - self.t_label_prot3.setText(_translate("MainWindow", "Protection Mode", None)) - self.t_label_comp_src3.setText(_translate("MainWindow", "Audio Source", None)) - self.t_label_path_src3.setText(_translate("MainWindow", "select audio", None)) - self.t_btn_path_src3.setText(_translate("MainWindow", "...", None)) - self.t_label_comp4.setText(_translate("MainWindow", "Component 4", None)) - self.t_label_rate4.setText(_translate("MainWindow", "Data rate [kbit/s]", None)) - self.t_label_prot4.setText(_translate("MainWindow", "Protection Mode", None)) - self.t_label_comp_src4.setText(_translate("MainWindow", "Audio Source", None)) - self.t_label_path_src4.setText(_translate("MainWindow", "select audio", None)) - self.t_btn_path_src4.setText(_translate("MainWindow", "...", None)) - self.t_label_comp5.setText(_translate("MainWindow", "Component 5", None)) - self.t_label_rate5.setText(_translate("MainWindow", "Data rate [kbit/s]", None)) - self.t_label_prot5.setText(_translate("MainWindow", "Protection Mode", None)) - self.t_label_comp_src5.setText(_translate("MainWindow", "Audio Source", None)) - self.t_label_path_src5.setText(_translate("MainWindow", "select audio", None)) - self.t_btn_path_src5.setText(_translate("MainWindow", "...", None)) - self.t_label_comp6.setText(_translate("MainWindow", "Component 6", None)) - self.t_label_rate6.setText(_translate("MainWindow", "Data rate [kbit/s]", None)) - self.t_label_prot6.setText(_translate("MainWindow", "Protection Mode", None)) - self.t_label_comp_src6.setText(_translate("MainWindow", "Audio Source", None)) - self.t_label_path_src6.setText(_translate("MainWindow", "select audio", None)) - self.t_btn_path_src6.setText(_translate("MainWindow", "...", None)) - self.t_label_comp7.setText(_translate("MainWindow", "Component 7", None)) - self.t_label_rate7.setText(_translate("MainWindow", "Data rate [kbit/s]", None)) - self.t_label_prot7.setText(_translate("MainWindow", "Protection Mode", None)) - self.t_label_comp_src7.setText(_translate("MainWindow", "Audio Source", None)) - self.t_label_path_src7.setText(_translate("MainWindow", "select audio", None)) - self.t_btn_path_src7.setText(_translate("MainWindow", "...", None)) - self.t_label_label1.setText(_translate("MainWindow", "Name", None)) - self.t_label_label2.setText(_translate("MainWindow", "Name", None)) - self.t_label_label3.setText(_translate("MainWindow", "Name", None)) - self.t_label_label4.setText(_translate("MainWindow", "Name", None)) - self.t_label_label5.setText(_translate("MainWindow", "Name", None)) - self.t_label_label6.setText(_translate("MainWindow", "Name", None)) - self.t_label_label7.setText(_translate("MainWindow", "Name", None)) - self.t_combo_dabplus1.setItemText(0, _translate("MainWindow", "DAB+", None)) - self.t_combo_dabplus1.setItemText(1, _translate("MainWindow", "DAB", None)) - self.t_combo_dabplus2.setItemText(0, _translate("MainWindow", "DAB+", None)) - self.t_combo_dabplus2.setItemText(1, _translate("MainWindow", "DAB", None)) - self.t_combo_dabplus3.setItemText(0, _translate("MainWindow", "DAB+", None)) - self.t_combo_dabplus3.setItemText(1, _translate("MainWindow", "DAB", None)) - self.t_combo_dabplus4.setItemText(0, _translate("MainWindow", "DAB+", None)) - self.t_combo_dabplus4.setItemText(1, _translate("MainWindow", "DAB", None)) - self.t_combo_dabplus5.setItemText(0, _translate("MainWindow", "DAB+", None)) - self.t_combo_dabplus5.setItemText(1, _translate("MainWindow", "DAB", None)) - self.t_combo_dabplus6.setItemText(0, _translate("MainWindow", "DAB+", None)) - self.t_combo_dabplus6.setItemText(1, _translate("MainWindow", "DAB", None)) - self.t_combo_dabplus7.setItemText(0, _translate("MainWindow", "DAB+", None)) - self.t_combo_dabplus7.setItemText(1, _translate("MainWindow", "DAB", None)) - self.t_combo_prot1.setItemText(0, _translate("MainWindow", "A1", None)) - self.t_combo_prot1.setItemText(1, _translate("MainWindow", "A2", None)) - self.t_combo_prot1.setItemText(2, _translate("MainWindow", "A3", None)) - self.t_combo_prot1.setItemText(3, _translate("MainWindow", "A4", None)) - self.t_combo_prot2.setItemText(0, _translate("MainWindow", "A1", None)) - self.t_combo_prot2.setItemText(1, _translate("MainWindow", "A2", None)) - self.t_combo_prot2.setItemText(2, _translate("MainWindow", "A3", None)) - self.t_combo_prot2.setItemText(3, _translate("MainWindow", "A4", None)) - self.t_combo_prot3.setItemText(0, _translate("MainWindow", "A1", None)) - self.t_combo_prot3.setItemText(1, _translate("MainWindow", "A2", None)) - self.t_combo_prot3.setItemText(2, _translate("MainWindow", "A3", None)) - self.t_combo_prot3.setItemText(3, _translate("MainWindow", "A4", None)) - self.t_combo_prot4.setItemText(0, _translate("MainWindow", "A1", None)) - self.t_combo_prot4.setItemText(1, _translate("MainWindow", "A2", None)) - self.t_combo_prot4.setItemText(2, _translate("MainWindow", "A3", None)) - self.t_combo_prot4.setItemText(3, _translate("MainWindow", "A4", None)) - self.t_combo_prot5.setItemText(0, _translate("MainWindow", "A1", None)) - self.t_combo_prot5.setItemText(1, _translate("MainWindow", "A2", None)) - self.t_combo_prot5.setItemText(2, _translate("MainWindow", "A3", None)) - self.t_combo_prot5.setItemText(3, _translate("MainWindow", "A4", None)) - self.t_combo_prot6.setItemText(0, _translate("MainWindow", "A1", None)) - self.t_combo_prot6.setItemText(1, _translate("MainWindow", "A2", None)) - self.t_combo_prot6.setItemText(2, _translate("MainWindow", "A3", None)) - self.t_combo_prot6.setItemText(3, _translate("MainWindow", "A4", None)) - self.t_combo_prot7.setItemText(0, _translate("MainWindow", "A1", None)) - self.t_combo_prot7.setItemText(1, _translate("MainWindow", "A2", None)) - self.t_combo_prot7.setItemText(2, _translate("MainWindow", "A3", None)) - self.t_combo_prot7.setItemText(3, _translate("MainWindow", "A4", None)) - self.t_label_audio_rate1.setText(_translate("MainWindow", "Audio settings", None)) - self.t_label_audio_rate2.setText(_translate("MainWindow", "Audio settings", None)) - self.t_label_audio_rate3.setText(_translate("MainWindow", "Audio sampling", None)) - self.t_label_audio_rate4.setText(_translate("MainWindow", "Audio sampling", None)) - self.t_label_audio_rate5.setText(_translate("MainWindow", "audio sampling", None)) - self.t_label_audio_rate6.setText(_translate("MainWindow", "Audio sampling", None)) - self.t_label_audio_rate7.setText(_translate("MainWindow", "Audio sampling", None)) - self.t_combo_stereo1.setItemText(0, _translate("MainWindow", "stereo", None)) - self.t_combo_stereo1.setItemText(1, _translate("MainWindow", "mono", None)) - self.t_combo_audio_rate1.setItemText(0, _translate("MainWindow", "32 kHz", None)) - self.t_combo_audio_rate1.setItemText(1, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab1.setItemText(0, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab1.setItemText(1, _translate("MainWindow", "24 kHz", None)) - self.t_combo_stereo2.setItemText(0, _translate("MainWindow", "stereo", None)) - self.t_combo_stereo2.setItemText(1, _translate("MainWindow", "mono", None)) - self.t_combo_audio_rate2.setItemText(0, _translate("MainWindow", "32 kHz", None)) - self.t_combo_audio_rate2.setItemText(1, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab2.setItemText(0, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab2.setItemText(1, _translate("MainWindow", "24 kHz", None)) - self.t_combo_stereo3.setItemText(0, _translate("MainWindow", "stereo", None)) - self.t_combo_stereo3.setItemText(1, _translate("MainWindow", "mono", None)) - self.t_combo_audio_rate3.setItemText(0, _translate("MainWindow", "32 kHz", None)) - self.t_combo_audio_rate3.setItemText(1, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab3.setItemText(0, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab3.setItemText(1, _translate("MainWindow", "24 kHz", None)) - self.t_combo_stereo4.setItemText(0, _translate("MainWindow", "stereo", None)) - self.t_combo_stereo4.setItemText(1, _translate("MainWindow", "mono", None)) - self.t_combo_audio_rate4.setItemText(0, _translate("MainWindow", "32 kHz", None)) - self.t_combo_audio_rate4.setItemText(1, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab4.setItemText(0, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab4.setItemText(1, _translate("MainWindow", "24 kHz", None)) - self.t_combo_stereo5.setItemText(0, _translate("MainWindow", "stereo", None)) - self.t_combo_stereo5.setItemText(1, _translate("MainWindow", "mono", None)) - self.t_combo_audio_rate5.setItemText(0, _translate("MainWindow", "32 kHz", None)) - self.t_combo_audio_rate5.setItemText(1, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab5.setItemText(0, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab5.setItemText(1, _translate("MainWindow", "24 kHz", None)) - self.t_combo_stereo6.setItemText(0, _translate("MainWindow", "stereo", None)) - self.t_combo_stereo6.setItemText(1, _translate("MainWindow", "mono", None)) - self.t_combo_audio_rate6.setItemText(0, _translate("MainWindow", "32 kHz", None)) - self.t_combo_audio_rate6.setItemText(1, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab6.setItemText(0, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab6.setItemText(1, _translate("MainWindow", "24 kHz", None)) - self.t_combo_stereo7.setItemText(0, _translate("MainWindow", "stereo", None)) - self.t_combo_stereo7.setItemText(1, _translate("MainWindow", "mono", None)) - self.t_combo_audio_rate7.setItemText(0, _translate("MainWindow", "32 kHz", None)) - self.t_combo_audio_rate7.setItemText(1, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab7.setItemText(0, _translate("MainWindow", "48 kHz", None)) - self.t_combo_audio_rate_dab7.setItemText(1, _translate("MainWindow", "24 kHz", None)) - self.t_label_increase_num_subch_info.setText(_translate("MainWindow", "increase \"Number of channels\" for more components", None)) - self.label_12.setText(_translate("MainWindow", "Ensemble info", None)) - self.label_13.setText(_translate("MainWindow", "Label", None)) - self.t_edit_ensemble_label.setText(_translate("MainWindow", "Galaxy News", None)) - self.label_14.setText(_translate("MainWindow", "Country", None)) - self.label_17.setText(_translate("MainWindow", "Number of channels", None)) - self.label_23.setText(_translate("MainWindow", "Language", None)) - self.t_btn_init.setText(_translate("MainWindow", "start transmitter", None)) - self.label_22.setText(_translate("MainWindow", "Status:", None)) - self.t_label_status.setText(_translate("MainWindow", "not running", None)) - self.label_20.setText(_translate("MainWindow", "Audio Player", None)) - self.label_18.setText(_translate("MainWindow", "Listen to component", None)) - self.t_btn_play.setText(_translate("MainWindow", " Play", None)) - self.t_btn_stop.setText(_translate("MainWindow", " Stop", None)) - self.label_19.setText(_translate("MainWindow", "Volume", None)) - self.mode_tabs.setTabText(self.mode_tabs.indexOf(self.tab_transmission), _translate("MainWindow", "Transmitter", None)) - diff --git a/python/GUI/user_frontend.ui b/python/GUI/user_frontend.ui index 3e40ff03..a0b78bac 100644 --- a/python/GUI/user_frontend.ui +++ b/python/GUI/user_frontend.ui @@ -6,7 +6,7 @@ 0 0 - 1146 + 1203 739 @@ -114,6 +114,13 @@ + + + + RTL-SDR + + + @@ -404,10 +411,10 @@ tfadsf - -20 + 0 - 20 + 40 0 @@ -420,7 +427,7 @@ - reception: + SNR: @@ -799,6 +806,40 @@ + + + + + + Gain + + + + + + + 100 + + + 50 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -954,7 +995,7 @@ 0 0 - 239 + 200 602 @@ -1020,7 +1061,7 @@ 1000000000 - 208064000 + 201072000 @@ -1151,8 +1192,8 @@ 0 - -1028 - 525 + 0 + 553 1514 @@ -2921,6 +2962,40 @@ + + + + + + Gain + + + + + + + 80 + + + 30 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + diff --git a/python/GUI/usrp_dab_rx.py b/python/GUI/usrp_dab_rx.py index 0f8986f3..9f763d2f 100644 --- a/python/GUI/usrp_dab_rx.py +++ b/python/GUI/usrp_dab_rx.py @@ -27,34 +27,25 @@ from gnuradio import audio, digital from gnuradio import qtgui from gnuradio import fft +import osmosdr import dab import time, math class usrp_dab_rx(gr.top_block): - def __init__(self, dab_mode, frequency, bit_rate, address, size, protection, audio_bit_rate, dabplus, use_usrp, src_path, sink_path = "None"): + def __init__(self, dab_mode, frequency, bit_rate, address, size, protection, audio_bit_rate, dabplus, use_usrp, use_rtl, src_path, sink_path = "None", prev_src=None): gr.top_block.__init__(self) self.dab_mode = dab_mode self.verbose = False - self.sample_rate = 2e6 + self.sample_rate = 2048e3 self.dabplus = dabplus self.use_usrp = use_usrp + self.use_rtl = use_rtl self.src_path = src_path self.sink_path = sink_path gr.log.set_level("warn") - ######################## - # source - ######################## - if self.use_usrp: - self.src = uhd.usrp_source("", uhd.io_type.COMPLEX_FLOAT32, 1) - self.src.set_samp_rate(self.sample_rate) - self.src.set_antenna("TX/RX") - else: - print "using file source" - self.src = blocks.file_source_make(gr.sizeof_gr_complex, self.src_path, False) - # set paramters to default mode self.softbits = True self.filter_input = True @@ -70,6 +61,37 @@ def __init__(self, dab_mode, frequency, bit_rate, address, size, protection, aud self.resample_fixed, self.verbose, self.correct_ffe, self.equalize_magnitude) + + ######################## + # source + ######################## + if self.use_usrp: + self.src = uhd.usrp_source("", uhd.io_type.COMPLEX_FLOAT32, 1) + self.src.set_clock_rate(self.sample_rate*8) + self.src.set_samp_rate(self.sample_rate) + self.src.set_gain(50, 0) + self.src.set_antenna("TX/RX") + + elif self.use_rtl: + if(prev_src is None): + self.src = osmosdr.source() + else: + self.src = prev_src + self.src.set_sample_rate(self.sample_rate) + self.src.set_center_freq(self.frequency) + self.src.set_freq_corr(0, 0) + self.src.set_dc_offset_mode(2, 0) + self.src.set_iq_balance_mode(0, 0) + self.src.set_gain_mode(False, 0) + self.src.set_gain(50, 0) + self.src.set_if_gain(20, 0) + self.src.set_bb_gain(20, 0) + self.src.set_antenna("", 0) + self.src.set_bandwidth(0, 0) + else: + print "using file source" + self.src = blocks.file_source_make(gr.sizeof_gr_complex, self.src_path, False) + ######################## # FFT and waterfall plot ######################## @@ -80,19 +102,19 @@ def __init__(self, dab_mode, frequency, bit_rate, address, size, protection, aud ######################## # OFDM demod ######################## - self.demod = dab.ofdm_demod(self.dab_params, self.rx_params, self.verbose) + self.demod = dab.ofdm_demod_cc(self.dab_params) ######################## # SNR measurement ######################## - self.v2s_snr = blocks.vector_to_stream_make(gr.sizeof_gr_complex, self.dab_params.num_carriers) - self.snr_measurement = digital.mpsk_snr_est_cc_make(digital.SNR_EST_SIMPLE, 10000) + self.v2s_snr = blocks.vector_to_stream(gr.sizeof_gr_complex*1, self.dab_params.num_carriers) self.constellation_plot = qtgui.const_sink_c_make(1024, "", 1) + self.constellation_plot.enable_grid(True) ######################## # FIC decoder ######################## - self.fic_dec = dab.fic_decode(self.dab_params) + self.fic_dec = dab.fic_decode_vc(self.dab_params) ######################## # MSC decoder @@ -113,6 +135,8 @@ def __init__(self, dab_mode, frequency, bit_rate, address, size, protection, aud ######################## self.valve_left = dab.valve_ff_make(True) self.valve_right= dab.valve_ff_make(True) + self.delay_left = blocks.delay_make(gr.sizeof_float, int(audio_bit_rate)) + self.delay_right = blocks.delay_make(gr.sizeof_float, int(audio_bit_rate)) self.audio = audio.sink_make(audio_bit_rate) self.wav_sink = blocks.wavfile_sink_make("dab_audio.wav", 2, audio_bit_rate) @@ -121,37 +145,31 @@ def __init__(self, dab_mode, frequency, bit_rate, address, size, protection, aud ######################## self.connect(self.src, self.fft_plot) self.connect(self.src, self.waterfall_plot) - self.connect(self.src, self.demod, (self.fic_dec, 0)) - self.connect((self.demod, 1), (self.fic_dec, 1)) + self.connect(self.src, self.demod, self.fic_dec) if self.dabplus: - self.connect((self.demod, 0), (self.dabplus, 0)) - self.connect((self.demod, 1), (self.dabplus, 1)) + self.connect((self.demod, 1), self.dabplus) else: self.connect((self.demod, 0), (self.msc_dec, 0), self.unpack, self.mp2_dec) self.connect((self.demod, 1), (self.msc_dec, 1)) self.connect((self.mp2_dec, 0), self.s2f_left, self.gain_left) self.connect((self.mp2_dec, 1), self.s2f_right, self.gain_right) - self.connect((self.demod, 0), self.v2s_snr, self.snr_measurement, self.constellation_plot) + self.connect((self.demod, 0), self.v2s_snr, self.constellation_plot) # connect audio to sound card and file sink if self.dabplus: - self.connect((self.dabplus, 0), (self.audio, 0)) - self.connect((self.dabplus, 1), (self.audio, 1)) + self.connect((self.dabplus, 0), self.delay_left, (self.audio, 0)) + self.connect((self.dabplus, 1), self.delay_right, (self.audio, 1)) self.connect((self.dabplus, 0), self.valve_left, (self.wav_sink, 0)) self.connect((self.dabplus, 1), self.valve_right, (self.wav_sink, 1)) else: - self.connect(self.gain_left, (self.audio, 0)) - self.connect(self.gain_right, (self.audio, 1)) + self.connect(self.gain_left, self.delay_left, (self.audio, 0)) + self.connect(self.gain_right, self.delay_right, (self.audio, 1)) self.connect(self.gain_left, self.valve_left, (self.wav_sink, 0)) self.connect(self.gain_right, self.valve_right, (self.wav_sink, 1)) # tune USRP frequency if self.use_usrp: self.set_freq(self.frequency) - # set gain - # if no gain was specified, use the mid-point in dB - g = self.src.get_gain_range() - self.rx_gain = float(g.start() + g.stop()) / 2 - self.src.set_gain(self.rx_gain) + ######################## # getter methods @@ -175,7 +193,7 @@ def get_sample_rate(self): return self.dabplus.get_sample_rate() def get_snr(self): - return self.snr_measurement.snr() + return self.demod.get_snr() def get_firecode_passed(self): return self.dabplus.get_firecode_passed() @@ -209,6 +227,10 @@ def set_freq(self, freq): print "-> error - cannot tune to " + str(freq) + " Hz" return False + def set_gain(self, gain): + if hasattr(self, 'src'): + self.src.set_gain(gain, 0) + def receive(self): rx = usrp_dab_rx() rx.run() diff --git a/python/GUI/usrp_dab_tx.py b/python/GUI/usrp_dab_tx.py index d3dcdc93..dd37c3aa 100644 --- a/python/GUI/usrp_dab_tx.py +++ b/python/GUI/usrp_dab_tx.py @@ -35,9 +35,8 @@ def __init__(self, dab_mode, frequency, num_subch, ensemble_label, service_label self.dab_mode = dab_mode self.frequency = frequency - interp = 64 - self.sample_rate = 128e6 / interp - self.dp = dab.parameters.dab_parameters(self.dab_mode, 2000000, False) + self.sample_rate = 2048000 + self.dp = dab.parameters.dab_parameters(self.dab_mode, 2048000, False) self.num_subch = num_subch self.ensemble_label = ensemble_label self.service_label = service_label @@ -108,9 +107,14 @@ def __init__(self, dab_mode, frequency, num_subch, ensemble_label, service_label ######################## if self.use_usrp: self.sink = uhd.usrp_sink("", uhd.io_type.COMPLEX_FLOAT32, 1) + self.sink.set_clock_rate(self.sample_rate * 8) self.sink.set_samp_rate(self.sample_rate) + self.sink.set_clock_source("gpsdo", 0) + self.sink.set_time_source("gpsdo", 0) self.sink.set_antenna("TX/RX") - self.sink.set_center_freq(self.frequency) + self.sink.set_gain(50, 0) + self.sink.set_center_freq(uhd.tune_request(self.frequency, 2*self.sample_rate)) + self.multiply = blocks.multiply_const_cc_make(0.3) else: self.sink = blocks.file_sink_make(gr.sizeof_gr_complex, self.sink_path) # audio sink @@ -148,7 +152,7 @@ def __init__(self, dab_mode, frequency, num_subch, ensemble_label, service_label self.connect((self.mux, 0), self.s2v_mod, (self.mod, 0)) self.connect(self.trigsrc, (self.mod, 1)) if use_usrp: - self.connect(self.mod, self.sink) + self.connect(self.mod, self.multiply, self.sink) else: self.connect(self.mod, blocks.throttle_make(gr.sizeof_gr_complex, 2e6), self.sink) #self.connect((self.msc_sources[self.selected_audio-1], 0), self.gain_left, (self.audio, 0)) @@ -162,3 +166,6 @@ def set_volume(self, volume): self.gain_left.set_k(volume) self.gain_right.set_k(volume) + def set_gain(self, gain): + if hasattr(self, 'sink'): + self.sink.set_gain(gain, 0) diff --git a/python/__init__.py b/python/__init__.py index dfaae6f9..bfbe1bca 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -19,30 +19,24 @@ # The presence of this file turns this directory into a Python package ''' -This is the GNU Radio DAB module. Place your Python package -description here (python/__init__.py). +This is the GNU Radio DAB module. ''' +# The presence of this file turns this directory into a Python package +import os + # import swig generated symbols into the dab namespace -try: - # this might fail if the module is python-only - from dab_swig import * -except ImportError: - pass +from dab_swig import * + +from parameters import * +from ofdm_demod_cc import * +from ofdm_mod_bc import * +from fic_decode_vc import * +from fic_encode import * +from msc_decode import * +from msc_encode import * +from transmitter_c import * +from dabplus_audio_decoder_ff import * -# import any pure python here -from ofdm_sync_dab import ofdm_sync_dab -from ofdm_sync_dab2 import ofdm_sync_dab2 -from detect_null import detect_null -from parameters import dab_parameters -from parameters import receiver_parameters -from ofdm import ofdm_mod -from ofdm import ofdm_demod -from fic import fic_decode -from msc_decode import msc_decode -from fic_encode import fic_encode -from msc_encode import msc_encode -from transmitter_c import transmitter_c -from dabplus_audio_decoder_ff import dabplus_audio_decoder_ff import constants -# + diff --git a/python/dab_estimate_samplerate.py b/python/dab_estimate_samplerate.py deleted file mode 100755 index 5e24fd31..00000000 --- a/python/dab_estimate_samplerate.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio 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. -# -# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -# Andreas Mueller, 2008 -# andrmuel@ee.ethz.ch - -""" -estimate the sample rate of DAB samples by looking at the Null symbols -""" - -from gnuradio import gr, blocks -from gnuradio.eng_option import eng_option -import dab -from optparse import OptionParser - -class estimate_samplerate(gr.top_block): - """ - @brief Estimate actual sample rate - - Looks for Null symbols and estimates the real sample rate by counting - the samples between two Null symbols. - """ - def __init__(self): - gr.top_block.__init__(self) - - usage = "%prog: [options] samples_file" - parser = OptionParser(option_class=eng_option, usage=usage) - parser.add_option("-m", "--dab-mode", type="int", default=1, - help="DAB mode [default=%default]") - parser.add_option('-u', '--usrp-source', action="store_true", default=False, - help="Samples from USRP (-> resample from 2 MSPS to 2.048 MSPS)") - (options, args) = parser.parse_args () - - dp = dab.dab_parameters(options.dab_mode) - filename = args[0] - - self.src = blocks.file_source(gr.sizeof_gr_complex, filename, False) - self.resample = blocks.rational_resampler_ccc(2048,2000) - self.rate_detect_ns = dab.detect_null.detect_null(dp.ns_length, False) - self.rate_estimator = dab.blocks.estimate_sample_rate_bf(dp.sample_rate, dp.frame_length) - self.decimate = blocks.keep_one_in_n(gr.sizeof_float, dp.frame_length) - self.ignore_first = blocks.skiphead(gr.sizeof_float, 1) - self.sink = blocks.vector_sink_f() - - if options.usrp_source: - self.connect(self.src, self.resample, self.rate_detect_ns, self.rate_estimator, self.decimate, self.ignore_first, self.sink) - else: - self.connect(self.src, self.rate_detect_ns, self.rate_estimator, self.decimate, self.ignore_first, self.sink) - - -if __name__=='__main__': - try: - es = estimate_samplerate() - es.run() - print "sample rate estimation (average): " + str(sum(es.sink.data())/len(es.sink.data())) + " SPS" - except KeyboardInterrupt: - pass - - diff --git a/python/dabplus_audio_decoder_ff.py b/python/dabplus_audio_decoder_ff.py index b6da1ae8..c617e854 100644 --- a/python/dabplus_audio_decoder_ff.py +++ b/python/dabplus_audio_decoder_ff.py @@ -39,15 +39,14 @@ def __init__(self, dab_params, bit_rate, address, subch_size, protection, output gr.hier_block2.__init__(self, "dabplus_audio_decoder_ff", # Input signature - gr.io_signature2(2, 2, gr.sizeof_float * dab_params.num_carriers * 2, gr.sizeof_char), + gr.io_signature(1, 1, gr.sizeof_gr_complex * dab_params.num_carriers), # Output signature gr.io_signature2(2, 2, gr.sizeof_float, gr.sizeof_float)) else: # output signed 16 bit integers (directly from decoder) gr.hier_block2.__init__(self, "dabplus_audio_decoder_ff", # Input signature - gr.io_signature2(2, 2, gr.sizeof_float * dab_params.num_carriers * 2, - gr.sizeof_char), + gr.io_signature(1, 1, gr.sizeof_float * dab_params.num_carriers), # Output signature gr.io_signature2(2, 2, gr.sizeof_short, gr.sizeof_short)) self.dp = dab_params @@ -75,8 +74,8 @@ def __init__(self, dab_params, bit_rate, address, subch_size, protection, output # mp4 decoder self.mp4 = dab.mp4_decode_bs_make(self.bit_rate_n) - self.connect((self, 0), (self.msc_decoder, 0), self.firecode, self.rs, self.mp4) - self.connect((self, 1), (self.msc_decoder, 1)) + # connections + self.connect(self, self.msc_decoder, self.firecode, self.rs, self.mp4) if self.output_float: # map short samples to the range [-1,1] in floats diff --git a/python/fic.py b/python/fic.py deleted file mode 100644 index 0c2e0e3d..00000000 --- a/python/fic.py +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio 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. -# -# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -# Andreas Mueller, 2008 -# andrmuel@ee.ethz.ch - -from gnuradio import gr, trellis, blocks -import dab_swig as dab -from math import sqrt - -""" -DAB FIC layer -""" - -class fic_decode(gr.hier_block2): - """ - @brief block to decode FIBs (fast information blocks) from the FIC (fast information channel) of a demodulated DAB signal - - - get FIBs from byte stream - - do convolutional decoding - - undo energy dispersal - - get FIC information - """ - - def __init__(self, dab_params, verbose=False, debug=False): - """ - Hierarchical block for FIC decoding - - @param dab_params DAB parameter object (dab.parameters.dab_parameters) - """ - gr.hier_block2.__init__(self, "fic", - gr.io_signature2(2, 2, gr.sizeof_float * dab_params.num_carriers * 2, gr.sizeof_char), - gr.io_signature(1, 1, gr.sizeof_char * 32)) - - self.dp = dab_params - self.verbose = verbose - self.debug = debug - - # FIB selection and block partitioning - self.select_fic_syms = dab.select_vectors(gr.sizeof_float, self.dp.num_carriers * 2, self.dp.num_fic_syms, 0) - self.repartition_fic = dab.repartition_vectors(gr.sizeof_float, self.dp.num_carriers * 2, - self.dp.fic_punctured_codeword_length, self.dp.num_fic_syms, - self.dp.num_cifs) - - # unpuncturing - self.unpuncture = dab.unpuncture_vff(self.dp.assembled_fic_puncturing_sequence, 0) - - # convolutional coding - # self.fsm = trellis.fsm(self.dp.conv_code_in_bits, self.dp.conv_code_out_bits, self.dp.conv_code_generator_polynomials) - self.fsm = trellis.fsm(1, 4, [0133, 0171, 0145, 0133]) # OK (dumped to text and verified partially) - self.conv_v2s = blocks.vector_to_stream(gr.sizeof_float, self.dp.fic_conv_codeword_length) - # self.conv_decode = trellis.viterbi_combined_fb(self.fsm, 20, 0, 0, 1, [1./sqrt(2),-1/sqrt(2)] , trellis.TRELLIS_EUCLIDEAN) - table = [ - 0, 0, 0, 0, - 0, 0, 0, 1, - 0, 0, 1, 0, - 0, 0, 1, 1, - 0, 1, 0, 0, - 0, 1, 0, 1, - 0, 1, 1, 0, - 0, 1, 1, 1, - 1, 0, 0, 0, - 1, 0, 0, 1, - 1, 0, 1, 0, - 1, 0, 1, 1, - 1, 1, 0, 0, - 1, 1, 0, 1, - 1, 1, 1, 0, - 1, 1, 1, 1 - ] - assert (len(table) / 4 == self.fsm.O()) - table = [(1 - 2 * x) / sqrt(2) for x in table] - self.conv_decode = trellis.viterbi_combined_fb(self.fsm, 774, 0, 0, 4, table, trellis.TRELLIS_EUCLIDEAN) - #self.conv_s2v = blocks.stream_to_vector(gr.sizeof_char, 774) - self.conv_prune = dab.prune(gr.sizeof_char, self.dp.fic_conv_codeword_length / 4, 0, - self.dp.conv_code_add_bits_input) - - # energy dispersal - self.prbs_src = blocks.vector_source_b(self.dp.prbs(self.dp.energy_dispersal_fic_vector_length), True) - #self.energy_v2s = blocks.vector_to_stream(gr.sizeof_char, self.dp.energy_dispersal_fic_vector_length) - self.add_mod_2 = blocks.xor_bb() - self.energy_s2v = blocks.stream_to_vector(gr.sizeof_char, self.dp.energy_dispersal_fic_vector_length) - self.cut_into_fibs = dab.repartition_vectors(gr.sizeof_char, self.dp.energy_dispersal_fic_vector_length, - self.dp.fib_bits, 1, self.dp.energy_dispersal_fic_fibs_per_vector) - - # connect all - self.nullsink = blocks.null_sink(gr.sizeof_char) - self.pack = blocks.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST) - self.fibout = blocks.stream_to_vector(1, 32) - # self.filesink = gr.file_sink(gr.sizeof_char, "debug/fic.dat") - self.fibsink = dab.fib_sink_vb() - - # self.connect((self,0), (self.select_fic_syms,0), (self.repartition_fic,0), self.unpuncture, self.conv_v2s, self.conv_decode, self.conv_s2v, self.conv_prune, self.energy_v2s, self.add_mod_2, self.energy_s2v, (self.cut_into_fibs,0), gr.vector_to_stream(1,256), gr.unpacked_to_packed_bb(1,gr.GR_MSB_FIRST), self.filesink) - self.connect((self, 0), - (self.select_fic_syms, 0), - (self.repartition_fic, 0), - self.unpuncture, - self.conv_v2s, - self.conv_decode, - #self.conv_s2v, - self.conv_prune, - #self.energy_v2s, - self.add_mod_2, - self.energy_s2v, - (self.cut_into_fibs, 0), - blocks.vector_to_stream(1, 256), - self.pack, - self.fibout, - self.fibsink) - self.connect(self.fibout, self) - self.connect(self.prbs_src, (self.add_mod_2, 1)) - self.connect((self, 1), (self.select_fic_syms, 1), (self.repartition_fic, 1), (self.cut_into_fibs, 1), - self.nullsink) - - if self.debug: - self.connect((self, 0), blocks.file_sink(gr.sizeof_float * self.dp.num_carriers * 2, "debug/transmission_frame.dat")) - self.connect((self, 1), blocks.file_sink(gr.sizeof_char, "debug/transmission_frame_trigger.dat")) - self.connect(self.select_fic_syms, blocks.file_sink(gr.sizeof_float * self.dp.num_carriers * 2, "debug/fic_select_syms.dat")) - self.connect(self.repartition_fic, blocks.file_sink(gr.sizeof_float * self.dp.fic_punctured_codeword_length, "debug/fic_repartitioned.dat")) - self.connect(self.unpuncture, blocks.file_sink(gr.sizeof_float * self.dp.fic_conv_codeword_length, "debug/fic_unpunctured.dat")) - self.connect(self.conv_decode, blocks.file_sink(gr.sizeof_char, "debug/fic_decoded.dat")) - self.connect(self.conv_prune, blocks.file_sink(gr.sizeof_char, "debug/fic_decoded_pruned.dat")) - #self.connect(self.conv_decode, blocks.file_sink(gr.sizeof_char * self.dp.energy_dispersal_fic_vector_length, "debug/fic_energy_dispersal_undone.dat")) - self.connect(self.pack, blocks.file_sink(gr.sizeof_char, "debug/fic_energy_undone.dat")) - - def get_ensemble_info(self): - return self.fibsink.get_ensemble_info() - - def get_service_info(self): - return self.fibsink.get_service_info() - - def get_service_labels(self): - return self.fibsink.get_service_labels() - - def get_subch_info(self): - return self.fibsink.get_subch_info() - - def get_programme_type(self): - return self.fibsink.get_programme_type() - - def get_crc_passed(self): - return self.fibsink.get_crc_passed() \ No newline at end of file diff --git a/python/fic_decode_vc.py b/python/fic_decode_vc.py new file mode 100644 index 00000000..0bb68223 --- /dev/null +++ b/python/fic_decode_vc.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). +# +# 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. +# + +from gnuradio import gr, trellis, blocks +import dab_swig as dab +from math import sqrt + +class fic_decode_vc(gr.hier_block2): + """ + @brief block to decode FIBs (fast information blocks) from the FIC (fast information channel) of a demodulated DAB signal + + - get demodulated FIC OFDM symbols from transmission frame + - do convolutional decoding + - undo energy dispersal + - get FIC information + """ + def __init__(self, dab_params): + gr.hier_block2.__init__(self, + "fic_decode_vc", + gr.io_signature(1, 1, gr.sizeof_gr_complex * dab_params.num_carriers), # Input signature + gr.io_signature(0, 0, gr.sizeof_char)) # Output signature + + self.dp = dab_params + + # complex to intereaved float for convolutional decoding + self.c2f = dab.complex_to_interleaved_float_vcf_make(self.dp.num_carriers) + + # FIB block partitioning + self.v2s = blocks.vector_to_stream_make(gr.sizeof_float, self.dp.num_carriers * 2) + self.s2v = blocks.stream_to_vector_make(gr.sizeof_float, self.dp.fic_punctured_codeword_length) + + # unpuncturing + self.unpuncture = dab.unpuncture_vff(self.dp.assembled_fic_puncturing_sequence, 0) + + # convolutional coding + self.fsm = trellis.fsm(1, 4, [0133, 0171, 0145, 0133]) # OK (dumped to text and verified partially) + self.conv_v2s = blocks.vector_to_stream(gr.sizeof_float, self.dp.fic_conv_codeword_length) + table = [ + 0, 0, 0, 0, + 0, 0, 0, 1, + 0, 0, 1, 0, + 0, 0, 1, 1, + 0, 1, 0, 0, + 0, 1, 0, 1, + 0, 1, 1, 0, + 0, 1, 1, 1, + 1, 0, 0, 0, + 1, 0, 0, 1, + 1, 0, 1, 0, + 1, 0, 1, 1, + 1, 1, 0, 0, + 1, 1, 0, 1, + 1, 1, 1, 0, + 1, 1, 1, 1 + ] + assert (len(table) / 4 == self.fsm.O()) + table = [(1 - 2 * x) / sqrt(2) for x in table] + self.conv_decode = trellis.viterbi_combined_fb(self.fsm, 774, 0, 0, 4, table, trellis.TRELLIS_EUCLIDEAN) + # self.conv_s2v = blocks.stream_to_vector(gr.sizeof_char, 774) + self.conv_prune = dab.prune(gr.sizeof_char, self.dp.fic_conv_codeword_length / 4, 0, + self.dp.conv_code_add_bits_input) + + # energy dispersal + self.prbs_src = blocks.vector_source_b(self.dp.prbs(self.dp.energy_dispersal_fic_vector_length), True) + # self.energy_v2s = blocks.vector_to_stream(gr.sizeof_char, self.dp.energy_dispersal_fic_vector_length) + self.add_mod_2 = blocks.xor_bb() + self.energy_s2v = blocks.stream_to_vector(gr.sizeof_char, self.dp.energy_dispersal_fic_vector_length) + + # connect all + self.nullsink = blocks.null_sink(gr.sizeof_char) + self.pack = blocks.unpacked_to_packed_bb(1, gr.GR_MSB_FIRST) + self.fibout = blocks.stream_to_vector(1, 32) + # self.filesink = gr.file_sink(gr.sizeof_char, "debug/fic.dat") + self.fibsink = dab.fib_sink_vb() + + + self.connect((self, 0), + self.c2f, + self.v2s, + self.s2v, + self.unpuncture, + self.conv_v2s, + self.conv_decode, + self.conv_prune, + self.add_mod_2, + self.pack, + self.fibout, + self.fibsink) + self.connect(self.prbs_src, (self.add_mod_2, 1)) + + def get_ensemble_info(self): + return self.fibsink.get_ensemble_info() + + def get_service_info(self): + return self.fibsink.get_service_info() + + def get_service_labels(self): + return self.fibsink.get_service_labels() + + def get_subch_info(self): + return self.fibsink.get_subch_info() + + def get_programme_type(self): + return self.fibsink.get_programme_type() + + def get_crc_passed(self): + return self.fibsink.get_crc_passed() diff --git a/python/msc_decode.py b/python/msc_decode.py index 712bbb49..2f7fe48b 100644 --- a/python/msc_decode.py +++ b/python/msc_decode.py @@ -40,7 +40,7 @@ def __init__(self, dab_params, address, size, protection, verbose=False, debug=F gr.hier_block2.__init__(self, "msc_decode", # Input signature - gr.io_signature2(2, 2, gr.sizeof_float * dab_params.num_carriers * 2, gr.sizeof_char), + gr.io_signature(1, 1, gr.sizeof_gr_complex * dab_params.num_carriers), # Output signature gr.io_signature(1, 1, gr.sizeof_char)) self.dp = dab_params @@ -77,27 +77,22 @@ def __init__(self, dab_params, address, size, protection, verbose=False, debug=F #sanity check assert(6*self.n == self.puncturing_L1[self.protect] + self.puncturing_L2[self.protect]) + # complex to interleaved float (part of the qpsk demodulation) + self.softbit_interleaver = dab.complex_to_interleaved_float_vcf(self.dp.num_carriers) - # MSC selection and block partitioning - # select OFDM carriers with MSC - self.select_msc_syms = dab.select_vectors(gr.sizeof_float, self.dp.num_carriers * 2, self.dp.num_msc_syms, - self.dp.num_fic_syms) - # repartition MSC data in CIFs (left out due to heavy burden for scheduler and not really necessary) - #self.repartition_msc_to_CIFs = dab.repartition_vectors_make(gr.sizeof_float, self.dp.num_carriers * 2, - # self.dp.cif_bits, self.dp.num_msc_syms, - # self.dp.num_cifs) - #repartition MSC to CUs - self.repartition_msc_to_cus = dab.repartition_vectors_make(gr.sizeof_float, self.dp.num_carriers*2, self.dp.msc_cu_size, self.dp.num_msc_syms, self.dp.num_cus * self.dp.num_cifs) - - # select CUs of one subchannel of each CIF and form logical frame vector - self.select_subch = dab.select_subch_vfvf_make(self.dp.msc_cu_size, self.dp.msc_cu_size * self.size, self.address, self.dp.num_cus) + # repartition vectors in capacity units (CUs) and select a sub-channel + self.v2s_repart_to_cus = blocks.vector_to_stream_make(gr.sizeof_float, self.dp.num_carriers*2) + self.s2v_repart_to_cus = blocks.stream_to_vector_make(gr.sizeof_float, self.dp.msc_cu_size) + self.select_subch = dab.select_cus_vfvf_make(self.dp.msc_cu_size, self.dp.num_cus, self.address, self.size) # time deinterleaving - self.time_v2s = blocks.vector_to_stream_make(gr.sizeof_float, self.dp.msc_cu_size * self.size) + self.time_v2s = blocks.vector_to_stream_make(gr.sizeof_float, self.dp.msc_cu_size) self.time_deinterleaver = dab.time_deinterleave_ff_make(self.dp.msc_cu_size * self.size, self.dp.scrambling_vector) + # unpuncture - self.conv_v2s = blocks.vector_to_stream(gr.sizeof_float, self.msc_punctured_codeword_length) - self.unpuncture = dab.unpuncture_ff_make(self.assembled_msc_puncturing_sequence, 0) + self.unpuncture_s2v = blocks.stream_to_vector(gr.sizeof_float, self.msc_punctured_codeword_length) + self.unpuncture = dab.unpuncture_vff_make(self.assembled_msc_puncturing_sequence, 0) + self.unpuncture_v2s = blocks.vector_to_stream(gr.sizeof_float, self.msc_conv_codeword_length) # convolutional decoding self.fsm = trellis.fsm(1, 4, [0133, 0171, 0145, 0133]) # OK (dumped to text and verified partially) @@ -128,40 +123,28 @@ def __init__(self, dab_params, address, size, protection, verbose=False, debug=F #energy descramble self.prbs_src = blocks.vector_source_b(self.dp.prbs(self.msc_I), True) - self.energy_v2s = blocks.vector_to_stream(gr.sizeof_char, self.msc_I) self.add_mod_2 = blocks.xor_bb() - #self.energy_s2v = blocks.stream_to_vector(gr.sizeof_char, self.msc_I) #pack bits self.pack_bits = blocks.unpacked_to_packed_bb_make(1, gr.GR_MSB_FIRST) # connect blocks - self.connect((self, 0), - (self.select_msc_syms, 0), - #(self.repartition_msc_to_CIFs, 0), - (self.repartition_msc_to_cus, 0), - (self.select_subch, 0), - #(self.repartition_cus_to_logical_frame, 0), + self.connect( + self, + self.softbit_interleaver, + self.v2s_repart_to_cus, + self.s2v_repart_to_cus, + self.select_subch, self.time_v2s, self.time_deinterleaver, - #self.conv_v2s, + self.unpuncture_s2v, self.unpuncture, + self.unpuncture_v2s, self.conv_decode, - #self.conv_s2v, self.conv_prune, - #self.energy_v2s, self.add_mod_2, self.pack_bits, - #self.energy_s2v, #better output stream or vector?? (self)) - #connect trigger chain - self.connect((self, 1), - (self.select_msc_syms, 1), - #(self.repartition_msc_to_CIFs, 1), - (self.repartition_msc_to_cus, 1), - #(self.select_subch, 1), - #(self.repartition_CUs_to_logical_frame, 1); - blocks.null_sink(gr.sizeof_char)) self.connect(self.prbs_src, (self.add_mod_2, 1)) diff --git a/python/ofdm.py b/python/ofdm.py deleted file mode 100644 index ccd90a56..00000000 --- a/python/ofdm.py +++ /dev/null @@ -1,294 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio 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. -# -# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -# the code in this file is partially adapted from ofdm.py from the gnuradio -# trunk (actually, only frequency synchronisation is done the same way, as that -# implementation otherwise is not suited for DAB) -# -# Andreas Mueller, 2008 -# andrmuel@ee.ethz.ch - -from gnuradio import gr, blocks, fft, filter, digital -import dab -from threading import Timer -from time import sleep -from math import pi - -""" -modulator and demodulator for the DAB physical layer -""" - -class ofdm_mod(gr.hier_block2): - """ - @brief Block to create a DAB signal from bits. - - Takes a data stream and performs OFDM modulation according to the DAB standard. - The output sample rate is 2.048 MSPS. - """ - - def __init__(self, dab_params, verbose=False, debug=False): - """ - Hierarchical block for OFDM modulation - - @param dab_params DAB parameter object (dab.parameters.dab_parameters) - @param debug enables debug output to files - """ - - dp = dab_params - - gr.hier_block2.__init__(self,"ofdm_mod", - gr.io_signature2(2, 2, gr.sizeof_char*dp.num_carriers/4, gr.sizeof_char), # input signature - gr.io_signature (1, 1, gr.sizeof_gr_complex)) # output signature - - - # symbol mapping - self.mapper_v2s = blocks.vector_to_stream_make(gr.sizeof_char, 384) - self.mapper_unpack = blocks.packed_to_unpacked_bb_make(1, gr.GR_MSB_FIRST) - self.mapper = dab.mapper_bc_make(dp.num_carriers) - self.mapper_s2v = blocks.stream_to_vector_make(gr.sizeof_gr_complex, 1536) - - # add pilot symbol - self.insert_pilot = dab.ofdm_insert_pilot_vcc(dp.prn) - - # phase sum - self.sum_phase = dab.sum_phasor_trig_vcc(dp.num_carriers) - - # frequency interleaving - self.interleave = dab.frequency_interleaver_vcc(dp.frequency_interleaving_sequence_array) - - # add central carrier & move to middle - self.move_and_insert_carrier = dab.ofdm_move_and_insert_zero(dp.fft_length, dp.num_carriers) - - # ifft - self.ifft = fft.fft_vcc(dp.fft_length, False, [], True) - - # cyclic prefixer - self.prefixer = digital.ofdm_cyclic_prefixer(dp.fft_length, dp.symbol_length) - - # convert back to vectors - self.s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, dp.symbol_length) - - # add null symbol - self.insert_null = dab.insert_null_symbol(dp.ns_length, dp.symbol_length) - - # - # connect it all - # - - # data - self.connect((self,0), self.mapper_v2s, self.mapper_unpack, self.mapper, self.mapper_s2v, (self.insert_pilot,0), (self.sum_phase,0), self.interleave, self.move_and_insert_carrier, self.ifft, self.prefixer, self.s2v, (self.insert_null,0)) - self.connect(self.insert_null, self) - - # control signal (frame start) - self.connect((self,1), (self.insert_pilot,1), (self.sum_phase,1), (self.insert_null,1)) - - if debug: - #self.connect(self.mapper, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/generated_signal_mapper.dat")) - self.connect(self.insert_pilot, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/generated_signal_insert_pilot.dat")) - self.connect(self.sum_phase, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/generated_signal_sum_phase.dat")) - self.connect(self.interleave, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/generated_signal_interleave.dat")) - self.connect(self.move_and_insert_carrier, blocks.file_sink(gr.sizeof_gr_complex*dp.fft_length, "debug/generated_signal_move_and_insert_carrier.dat")) - self.connect(self.ifft, blocks.file_sink(gr.sizeof_gr_complex*dp.fft_length, "debug/generated_signal_ifft.dat")) - self.connect(self.prefixer, blocks.file_sink(gr.sizeof_gr_complex, "debug/generated_signal_prefixer.dat")) - self.connect(self.insert_null, blocks.file_sink(gr.sizeof_gr_complex, "debug/generated_signal.dat")) - - - -class ofdm_demod(gr.hier_block2): - """ - @brief Block to demodulate a DAB signal into bits. - - Takes a stream of complex baseband samples and performs OFDM demodulation according to the DAB standard. - Expects an input sample rate of 2.048 MSPS. - """ - - def __init__(self, dab_params, rx_params, verbose=False, debug=False): - """ - Hierarchical block for OFDM demodulation - - @param dab_params DAB parameter object (dab.parameters.dab_parameters) - @param rx_params RX parameter object (dab.parameters.receiver_parameters) - @param debug enables debug output to files - @param verbose whether to produce verbose messages - """ - - self.dp = dp = dab_params - self.rp = rp = rx_params - self.verbose = verbose - - if self.rp.softbits: - gr.hier_block2.__init__(self,"ofdm_demod", - gr.io_signature (1, 1, gr.sizeof_gr_complex), # input signature - gr.io_signature2(2, 2, gr.sizeof_float*self.dp.num_carriers*2, gr.sizeof_char)) # output signature - else: - gr.hier_block2.__init__(self,"ofdm_demod", - gr.io_signature (1, 1, gr.sizeof_gr_complex), # input signature - gr.io_signature2(2, 2, gr.sizeof_char*self.dp.num_carriers/4, gr.sizeof_char)) # output signature - - - - # workaround for a problem that prevents connecting more than one block directly (see trac ticket #161) - #self.input = gr.kludge_copy(gr.sizeof_gr_complex) - self.input = blocks.multiply_const_cc(1.0) # FIXME - self.connect(self, self.input) - - # input filtering - if self.rp.input_fft_filter: - if verbose: print "--> RX filter enabled" - lowpass_taps = filter.firdes_low_pass(1.0, # gain - dp.sample_rate, # sampling rate - rp.filt_bw, # cutoff frequency - rp.filt_tb, # width of transition band - filter.firdes.WIN_HAMMING) # Hamming window - self.fft_filter = filter.fft_filter_ccc(1, lowpass_taps) - - - # correct sample rate offset, if enabled - if self.rp.autocorrect_sample_rate: - if verbose: print "--> dynamic sample rate correction enabled" - self.rate_detect_ns = dab.detect_null(dp.ns_length, False) - self.rate_estimator = dab.estimate_sample_rate_bf(dp.sample_rate, dp.frame_length) - self.rate_prober = blocks.probe_signal_f() - self.connect(self.input, self.rate_detect_ns, self.rate_estimator, self.rate_prober) - # self.resample = gr.fractional_interpolator_cc(0, 1) - self.resample = dab.fractional_interpolator_triggered_update_cc(0,1) - self.connect(self.rate_detect_ns, (self.resample,1)) - self.updater = Timer(0.1,self.update_correction) - # self.updater = threading.Thread(target=self.update_correction) - self.run_interpolater_update_thread = True - self.updater.setDaemon(True) - self.updater.start() - else: - self.run_interpolater_update_thread = False - if self.rp.sample_rate_correction_factor != 1: - if verbose: print "--> static sample rate correction enabled" - self.resample = gr.fractional_interpolator_cc(0, self.rp.sample_rate_correction_factor) - - # timing and fine frequency synchronisation - self.sync = dab.ofdm_sync_dab2(self.dp, self.rp, debug) - - # ofdm symbol sampler - self.sampler = dab.ofdm_sampler(dp.fft_length, dp.cp_length, dp.symbols_per_frame, rp.cp_gap) - - # fft for symbol vectors - self.fft = fft.fft_vcc(dp.fft_length, True, [], True) - - # coarse frequency synchronisation - self.cfs = dab.ofdm_coarse_frequency_correct(dp.fft_length, dp.num_carriers, dp.cp_length) - - # diff phasor - self.phase_diff = dab.diff_phasor_vcc(dp.num_carriers) - - # remove pilot symbol - self.remove_pilot = dab.ofdm_remove_first_symbol_vcc(dp.num_carriers) - - # magnitude equalisation - if self.rp.equalize_magnitude: - if verbose: print "--> magnitude equalization enabled" - self.equalizer = dab.magnitude_equalizer_vcc(dp.num_carriers, rp.symbols_for_magnitude_equalization) - - # frequency deinterleaving - self.deinterleave = dab.frequency_interleaver_vcc(dp.frequency_deinterleaving_sequence_array) - - # symbol demapping - self.demapper = dab.qpsk_demapper_vcb(dp.num_carriers) - - # - # connect everything - # - - if self.rp.autocorrect_sample_rate or self.rp.sample_rate_correction_factor != 1: - self.connect(self.input, self.resample) - self.input2 = self.resample - else: - self.input2 = self.input - if self.rp.input_fft_filter: - self.connect(self.input2, self.fft_filter, self.sync) - else: - self.connect(self.input2, self.sync) - - # data stream - self.connect((self.sync, 0), (self.sampler, 0), self.fft, (self.cfs, 0), self.phase_diff, (self.remove_pilot,0)) - if self.rp.equalize_magnitude: - self.connect((self.remove_pilot,0), (self.equalizer,0), self.deinterleave) - else: - self.connect((self.remove_pilot,0), self.deinterleave) - if self.rp.softbits: - if verbose: print "--> using soft bits" - self.softbit_interleaver = dab.complex_to_interleaved_float_vcf(self.dp.num_carriers) - self.connect(self.deinterleave, self.softbit_interleaver, (self,0)) - else: - self.connect(self.deinterleave, self.demapper, (self,0)) - - # control stream - self.connect((self.sync, 1), (self.sampler, 1), (self.cfs, 1), (self.remove_pilot,1)) - if self.rp.equalize_magnitude: - self.connect((self.remove_pilot,1), (self.equalizer,1), (self,1)) - else: - self.connect((self.remove_pilot,1), (self,1)) - - # calculate an estimate of the SNR - self.phase_var_decim = blocks.keep_one_in_n(gr.sizeof_gr_complex*self.dp.num_carriers, self.rp.phase_var_estimate_downsample) - self.phase_var_arg = blocks.complex_to_arg(dp.num_carriers) - self.phase_var_v2s = blocks.vector_to_stream(gr.sizeof_float, dp.num_carriers) - self.phase_var_mod = dab.modulo_ff(pi/2) - self.phase_var_avg_mod = filter.iir_filter_ffd([rp.phase_var_estimate_alpha], [0,1-rp.phase_var_estimate_alpha]) - self.phase_var_sub_avg = blocks.sub_ff() - self.phase_var_sqr = blocks.multiply_ff() - self.phase_var_avg = filter.iir_filter_ffd([rp.phase_var_estimate_alpha], [0,1-rp.phase_var_estimate_alpha]) - self.probe_phase_var = blocks.probe_signal_f() - self.connect((self.remove_pilot,0), self.phase_var_decim, self.phase_var_arg, self.phase_var_v2s, self.phase_var_mod, (self.phase_var_sub_avg,0), (self.phase_var_sqr,0)) - self.connect(self.phase_var_mod, self.phase_var_avg_mod, (self.phase_var_sub_avg,1)) - self.connect(self.phase_var_sub_avg, (self.phase_var_sqr,1)) - self.connect(self.phase_var_sqr, self.phase_var_avg, self.probe_phase_var) - - # measure processing rate - self.measure_rate = dab.measure_processing_rate(gr.sizeof_gr_complex, 2000000) - self.connect(self.input, self.measure_rate) - - # debugging - if debug: - self.connect(self.fft, blocks.file_sink(gr.sizeof_gr_complex*dp.fft_length, "debug/ofdm_after_fft.dat")) - self.connect((self.cfs,0), blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_after_cfs.dat")) - self.connect(self.phase_diff, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_diff_phasor.dat")) - self.connect((self.remove_pilot,0), blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_pilot_removed.dat")) - self.connect((self.remove_pilot,1), blocks.file_sink(gr.sizeof_char, "debug/ofdm_after_cfs_trigger.dat")) - self.connect(self.deinterleave, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_deinterleaved.dat")) - if self.rp.equalize_magnitude: - self.connect(self.equalizer, blocks.file_sink(gr.sizeof_gr_complex*dp.num_carriers, "debug/ofdm_equalizer.dat")) - if self.rp.softbits: - self.connect(self.softbit_interleaver, blocks.file_sink(gr.sizeof_float*dp.num_carriers*2, "debug/softbits.dat")) - - def clear_state(self): - self.sync.clear_state() - - def update_correction(self): - while self.run_interpolater_update_thread: - rate = self.rate_prober.level() - if rate!=0: - self.resample.set_interp_ratio(rate/self.dp.sample_rate) - sleep(0.1) - - def stop(self): - if self.run_interpolater_update_thread: - self.run_interpolater_update_thread = False - self.updater.join() diff --git a/python/ofdm_demod_cc.py b/python/ofdm_demod_cc.py new file mode 100644 index 00000000..6741ebce --- /dev/null +++ b/python/ofdm_demod_cc.py @@ -0,0 +1,87 @@ +# +# Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). +# +# 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. +# + +from gnuradio import gr, blocks +from gnuradio import fft +from gnuradio import digital +from math import sqrt +import dab + +class ofdm_demod_cc(gr.hier_block2): + """ + @brief block to demodulate the DAB OFDM + + - fine time and frequency synchronization + - FFT + - coarse frequency correction (sub-carrier assignment) + - differential phasor + - phase correction with phase reference symbol + - frequency deinterleaving + - demux into FIC and MSC + - output of complex qpsk symbols, separated after FIC and MSC + """ + def __init__(self, dab_params): + gr.hier_block2.__init__(self, + "ofdm_demod_cc", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(2, 2, gr.sizeof_gr_complex*1536)) # Output signature + + self.dp = dab_params + + # fine time and frequency synchronization + self.sync = dab.ofdm_synchronization_cvf_make(self.dp.fft_length, + self.dp.cp_length, + self.dp.fft_length, + self.dp.symbols_per_frame) + + # FFT + self.s2v_fft = blocks.stream_to_vector_make(gr.sizeof_gr_complex, self.dp.fft_length) + self.fft = fft.fft_vcc(self.dp.fft_length, True, [], True) + self.multiply = blocks.multiply_const_vcc([1.0/sqrt(2048)]*self.dp.fft_length) + + # coarse frequency correction (sub-carrier assignment) + self.coarse_freq_corr = dab.ofdm_coarse_frequency_correction_vcvc_make(self.dp.fft_length, + self.dp.num_carriers, + self.dp.cp_length) + + # differential phasor + self.differential_phasor = dab.diff_phasor_vcc_make(1536) + + # frequency deinterleaving + self.frequency_deinterleaver = dab.frequency_interleaver_vcc_make(self.dp.frequency_deinterleaving_sequence_array) + + # demux into FIC and MSC + self.demux = dab.demux_cc_make(self.dp.num_carriers, self.dp.num_fic_syms, self.dp.num_msc_syms) + + self.connect( + self, + self.sync, + self.s2v_fft, + self.fft, + self.multiply, + self.coarse_freq_corr, + self.differential_phasor, + self.frequency_deinterleaver, + self.demux, + (self, 0) + ) + self.connect((self.demux, 1), (self, 1)) + + def get_snr(self): + return self.coarse_freq_corr.get_snr() diff --git a/python/ofdm_mod_bc.py b/python/ofdm_mod_bc.py new file mode 100644 index 00000000..7bf2c241 --- /dev/null +++ b/python/ofdm_mod_bc.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +# the code in this file is partially adapted from ofdm.py from the gnuradio +# trunk (actually, only frequency synchronisation is done the same way, as that +# implementation otherwise is not suited for DAB) +# +# Andreas Mueller, 2008 +# andrmuel@ee.ethz.ch + +from gnuradio import gr, blocks, fft, filter, digital +import dab +from threading import Timer +from time import sleep +from math import pi +from math import sqrt + +""" +OFDM modulator for DAB/DAB+ +""" + + +class ofdm_mod(gr.hier_block2): + """ + @brief Block to create a DAB signal from bits. + + Takes a data stream and performs OFDM modulation according to the DAB standard. + The output sample rate is 2.048 MSPS. + """ + + def __init__(self, dab_params, verbose=False, debug=False): + """ + Hierarchical block for OFDM modulation + + @param dab_params DAB parameter object (dab.parameters.dab_parameters) + @param debug enables debug output to files + """ + + dp = dab_params + + gr.hier_block2.__init__(self, "ofdm_mod", + gr.io_signature2(2, 2, gr.sizeof_char * dp.num_carriers / 4, gr.sizeof_char), + # input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # output signature + + # symbol mapping + self.mapper = dab.qpsk_mapper_vbvc(dp.num_carriers) + + # add pilot symbol + self.insert_pilot = dab.ofdm_insert_pilot_vcc(dp.prn) + + # phase sum + self.sum_phase = dab.sum_phasor_trig_vcc(dp.num_carriers) + + # frequency interleaving + self.interleave = dab.frequency_interleaver_vcc(dp.frequency_interleaving_sequence_array) + + # add central carrier & move to middle + self.move_and_insert_carrier = dab.ofdm_move_and_insert_zero(dp.fft_length, dp.num_carriers) + + # ifft + self.ifft = fft.fft_vcc(dp.fft_length, False, [], True) + + # cyclic prefixer + self.prefixer = digital.ofdm_cyclic_prefixer(dp.fft_length, dp.symbol_length) + + # normalize to energy = 1 after IFFT + self.multiply_const = blocks.multiply_const_cc(1.0 / sqrt(2048)) + + # convert back to vectors + self.s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, dp.symbol_length) + + # add null symbol + self.insert_null = dab.insert_null_symbol(dp.ns_length, dp.symbol_length) + + # data + self.connect((self, 0), self.mapper, (self.insert_pilot, 0), (self.sum_phase, 0), self.interleave, + self.move_and_insert_carrier, self.ifft, self.prefixer, self.multiply_const, self.s2v, + (self.insert_null, 0)) + self.connect(self.insert_null, self) + + # control signal (frame start) + self.connect((self, 1), (self.insert_pilot, 1), (self.sum_phase, 1), (self.insert_null, 1)) + + if debug: + self.connect(self.mapper, + blocks.file_sink(gr.sizeof_gr_complex * dp.num_carriers, "debug/generated_signal_mapper.dat")) + self.connect(self.insert_pilot, blocks.file_sink(gr.sizeof_gr_complex * dp.num_carriers, + "debug/generated_signal_pilot_inserted.dat")) + self.connect(self.sum_phase, blocks.file_sink(gr.sizeof_gr_complex * dp.num_carriers, + "debug/generated_signal_sum_phase.dat")) + self.connect(self.interleave, blocks.file_sink(gr.sizeof_gr_complex * dp.num_carriers, + "debug/generated_signal_interleave.dat")) + self.connect(self.move_and_insert_carrier, blocks.file_sink(gr.sizeof_gr_complex * dp.fft_length, + "debug/generated_signal_move_and_insert_carrier.dat")) + self.connect(self.ifft, + blocks.file_sink(gr.sizeof_gr_complex * dp.fft_length, "debug/generated_signal_ifft.dat")) + self.connect(self.prefixer, blocks.file_sink(gr.sizeof_gr_complex, "debug/generated_signal_prefixer.dat")) + self.connect(self.insert_null, blocks.file_sink(gr.sizeof_gr_complex, "debug/generated_signal.dat")) diff --git a/python/ofdm_sync_dab.py b/python/ofdm_sync_dab.py deleted file mode 100644 index d83727c4..00000000 --- a/python/ofdm_sync_dab.py +++ /dev/null @@ -1,117 +0,0 @@ -# _*_ coding: utf8 _*_ - -# Copyright 2008 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio 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. -# -# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -# Andreas Mueller, 2008 -# andrmuel@ee.ethz.ch - -from gnuradio import gr -from gnuradio import blocks, analog -import dab -import sys -from math import pi - -class ofdm_sync_dab(gr.hier_block2): - """ - @brief OFDM Energy based time synchronisation and coarse frequency synchronisation for DAB signals - - This block implements synchronisation. Time synchronisation is done by using the NULL symbols. - Fine frequency synchronisation is done by correlating the cyclic prefix with the last part of the symbol. - - In contrast to the first version, this block averages over multiple symbols to get better fine frequency error estimates. - """ - def __init__(self, dab_params, rx_params, debug=False): - """ - OFDM time and coarse frequency synchronisation for DAB - - @param mode DAB mode (1-4) - @param debug if True: write data streams out to files - """ - - dp = dab_params - rp = rx_params - - gr.hier_block2.__init__(self,"ofdm_sync_dab", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # input signature - gr.io_signature2(2, 2, gr.sizeof_gr_complex, gr.sizeof_char)) # output signature - - # workaround for a problem that prevents connecting more than one block directly (see trac ticket #161) - self.input = gr.kludge_copy(gr.sizeof_gr_complex) - self.connect(self, self.input) - - # - # null-symbol detection - # - # (outsourced to detect_zero.py) - - self.ns_detect = detect_null.detect_null(dp.ns_length, debug) - self.connect(self.input, self.ns_detect) - - # - # fine frequency synchronisation - # - - # the code for fine frequency synchronisation is adapted from - # ofdm_sync_ml.py; it abuses the cyclic prefix to find the fine - # frequency error, as suggested in "ML Estimation of Timing and - # Frequency Offset in OFDM Systems", by Jan-Jaap van de Beek, - # Magnus Sandell, Per Ola Börjesson, see - # http://www.sm.luth.se/csee/sp/research/report/bsb96r.html - - self.ffs_delay = blocks.delay(gr.sizeof_gr_complex, dp.fft_length) - self.ffs_conj = blocks.conjugate_cc() - self.ffs_mult = blocks.multiply_cc() - self.ffs_moving_sum = dab_swig.moving_sum_cc(dp.cp_length) - self.ffs_arg = blocks.complex_to_arg() - self.ffs_sample_and_average = dab_swig.ofdm_ffs_sample(dp.symbol_length, dp.fft_length, rp.symbols_for_ffs_estimation, rp.ffs_alpha, dp.sample_rate) - if rp.correct_ffe: - self.ffs_delay_input_for_correction = blocks.delay(gr.sizeof_gr_complex, dp.symbol_length*rp.symbols_for_ffs_estimation) # by delaying the input, we can use the ff offset estimation from the first symbol to correct the first symbol itself - self.ffs_delay_frame_start = blocks.delay(gr.sizeof_char, dp.symbol_length*rp.symbols_for_ffs_estimation) # sample the value at the end of the symbol .. - self.ffs_nco = analog.frequency_modulator_fc(1) # ffs_sample_and_hold directly outputs phase error per sample - self.ffs_mixer = blocks.multiply_cc() - - # calculate fine frequency error - self.connect(self.input, self.ffs_conj, self.ffs_mult) - self.connect(self.input, self.ffs_delay, (self.ffs_mult, 1)) - self.connect(self.ffs_mult, self.ffs_moving_sum, self.ffs_arg, (self.ffs_sample_and_average, 0)) - self.connect(self.ns_detect, (self.ffs_sample_and_average, 1)) - - if rp.correct_ffe: - # do the correction - self.connect(self.ffs_sample_and_average, self.ffs_nco, (self.ffs_mixer, 0)) - self.connect(self.input, self.ffs_delay_input_for_correction, (self.ffs_mixer, 1)) - # output - corrected signal and start of DAB frames - self.connect(self.ffs_mixer, (self, 0)) - self.connect(self.ns_detect, self.ffs_delay_frame_start, (self, 1)) - else: - # just patch the signal through - self.connect(self.ffs_sample_and_average, blocks.null_sink(gr.sizeof_float)) - self.connect(self.input, (self,0)) - # frame start still needed .. - self.connect(self.ns_detect, (self,1)) - - if debug: - self.connect(self.ffs_sample_and_average, blocks.multiply_const_ff(1./(dp.T*2*pi)), gr.file_sink(gr.sizeof_float, "debug/ofdm_sync_dab_fine_freq_err_f.dat")) - self.connect(self.ffs_mixer, blocks.file_sink(gr.sizeof_gr_complex, "debug/ofdm_sync_dab_fine_freq_corrected_c.dat")) - - def clear_state(self): - self.ffs_moving_sum.reset() - self.ns_detect.clear_state() diff --git a/python/ofdm_sync_dab2.py b/python/ofdm_sync_dab2.py deleted file mode 100644 index fa8ed574..00000000 --- a/python/ofdm_sync_dab2.py +++ /dev/null @@ -1,109 +0,0 @@ -# _*_ coding: utf8 _*_ - -# Copyright 2008 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio 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. -# -# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -# Andreas Mueller, 2008 -# andrmuel@ee.ethz.ch - -from gnuradio import gr, blocks, analog -import dab -import sys -from math import pi - -class ofdm_sync_dab2(gr.hier_block2): - """ - @brief OFDM Energy based time synchronisation and coarse frequency synchronisation for DAB signals - - This block implements synchronisation. Time synchronisation is done by using the NULL symbols. - Fine frequency synchronisation is done by correlating the cyclic prefix with the last part of the symbol. - - In contrast to the first version, this block averages over multiple symbols to get better fine frequency error estimates. - """ - def __init__(self, dab_params, rx_params, debug=False): - """ - OFDM time and coarse frequency synchronisation for DAB - - @param mode DAB mode (1-4) - @param debug if True: write data streams out to files - """ - - dp = dab_params - rp = rx_params - - gr.hier_block2.__init__(self,"ofdm_sync_dab", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # input signature - gr.io_signature2(2, 2, gr.sizeof_gr_complex, gr.sizeof_char)) # output signature - - # workaround for a problem that prevents connecting more than one block directly (see trac ticket #161) - #self.input = gr.kludge_copy(gr.sizeof_gr_complex) - self.input = blocks.multiply_const_cc(1) # FIXME - self.connect(self, self.input) - - # - # null-symbol detection - # - # (outsourced to detect_zero.py) - - self.ns_detect = dab.detect_null(dp.ns_length, debug) - self.connect(self.input, self.ns_detect) - - # - # fine frequency synchronisation - # - - # the code for fine frequency synchronisation is adapted from - # ofdm_sync_ml.py; it abuses the cyclic prefix to find the fine - # frequency error, as suggested in "ML Estimation of Timing and - # Frequency Offset in OFDM Systems", by Jan-Jaap van de Beek, - # Magnus Sandell, Per Ola Börjesson, see - # http://www.sm.luth.se/csee/sp/research/report/bsb96r.html - - self.ffe = dab.ofdm_ffe_all_in_one(dp.symbol_length, dp.fft_length, rp.symbols_for_ffs_estimation, rp.ffs_alpha, int(dp.sample_rate)) - if rp.correct_ffe: - self.ffs_delay_input_for_correction = blocks.delay(gr.sizeof_gr_complex, dp.symbol_length*rp.symbols_for_ffs_estimation) # by delaying the input, we can use the ff offset estimation from the first symbol to correct the first symbol itself - self.ffs_delay_frame_start = blocks.delay(gr.sizeof_char, dp.symbol_length*rp.symbols_for_ffs_estimation) # sample the value at the end of the symbol .. - self.ffs_nco = analog.frequency_modulator_fc(1) # ffs_sample_and_hold directly outputs phase error per sample - self.ffs_mixer = blocks.multiply_cc() - - # calculate fine frequency error - self.connect(self.input, (self.ffe, 0)) - self.connect(self.ns_detect, (self.ffe, 1)) - - if rp.correct_ffe: - # do the correction - self.connect(self.ffe, self.ffs_nco, (self.ffs_mixer, 0)) - self.connect(self.input, self.ffs_delay_input_for_correction, (self.ffs_mixer, 1)) - # output - corrected signal and start of DAB frames - self.connect(self.ffs_mixer, (self, 0)) - self.connect(self.ns_detect, self.ffs_delay_frame_start, (self, 1)) - else: - # just patch the signal through - self.connect(self.ffe, blocks.null_sink(gr.sizeof_float)) - self.connect(self.input, (self,0)) - # frame start still needed .. - self.connect(self.ns_detect, (self,1)) - - if debug: - self.connect(self.ffe, blocks.multiply_const_ff(1./(dp.T*2*pi)), blocks.file_sink(gr.sizeof_float, "debug/ofdm_sync_dab_fine_freq_err_f.dat")) - #self.connect(self.ffs_mixer, blocks.file_sink(gr.sizeof_gr_complex, "debug/ofdm_sync_dab_fine_freq_corrected_c.dat")) - - def clear_state(self): - self.ns_detect.clear_state() diff --git a/python/qa/qa_complex_to_interleaved_float_vcf.py b/python/qa/qa_complex_to_interleaved_float_vcf.py index bf08ade4..a05f30c7 100755 --- a/python/qa/qa_complex_to_interleaved_float_vcf.py +++ b/python/qa/qa_complex_to_interleaved_float_vcf.py @@ -2,35 +2,36 @@ from gnuradio import gr, gr_unittest from gnuradio import blocks -import dab +import dab_swig as dab + class qa_complex_to_interleaved_float_vcf(gr_unittest.TestCase): - """ - @brief QA for the complex to interleaved float block - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_complex_to_interleaved_float_vcf(self): - src_data = (1+2j,3+4j,5+6j,7+8j) - expected_result = (1,3,2,4,5,7,6,8) - src = blocks.vector_source_c(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, 2) - complex_to_interleaved_float_vcf = dab.complex_to_interleaved_float_vcf(2) - v2s = blocks.vector_to_stream(gr.sizeof_float, 4) - dst = blocks.vector_sink_f() - self.tb.connect(src, s2v, complex_to_interleaved_float_vcf, v2s, dst) - self.tb.run() - result_data = dst.data() - # print result_data - self.assertFloatTuplesAlmostEqual(expected_result, result_data, 6) + """ + @brief QA for the complex to interleaved float block -if __name__ == '__main__': - gr_unittest.main() + This class implements a test bench to verify the corresponding C++ class. + """ + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + def test_001_complex_to_interleaved_float_vcf(self): + src_data = (1 + 2j, 3 + 4j, 5 + 6j, 7 + 8j) + expected_result = (1, 3, 2, 4, 5, 7, 6, 8) + src = blocks.vector_source_c(src_data) + s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, 2) + complex_to_interleaved_float_vcf = dab.complex_to_interleaved_float_vcf(2) + v2s = blocks.vector_to_stream(gr.sizeof_float, 4) + dst = blocks.vector_sink_f() + self.tb.connect(src, s2v, complex_to_interleaved_float_vcf, v2s, dst) + self.tb.run() + result_data = dst.data() + # print result_data + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 6) + + +if __name__ == '__main__': + gr_unittest.main() diff --git a/python/qa/qa_concatenate_signals.py b/python/qa/qa_concatenate_signals.py deleted file mode 100755 index 208f93a8..00000000 --- a/python/qa/qa_concatenate_signals.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env python - -import os -from gnuradio import gr, gr_unittest -from gnuradio import blocks -import dab - -class qa_concatenate_signals(gr_unittest.TestCase): - """ - @brief QA for signal concatenation block. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - os.environ['GR_SCHEDULER'] = "STS" # need single threaded scheduler for use with concatenate_signals - - def tearDown(self): - self.tb = None - - def test_001_concatenate_signals(self): - src_data0 = [1j,2j,3j,4j,5j] - src_data1 = [6j,7j,8j] - src_data2 = [9j,10j,11j,12j,13j,14j] - expected_result = src_data0 + src_data1 + src_data2 - src0 = blocks.vector_source_c(src_data0) - src1 = blocks.vector_source_c(src_data1) - src2 = blocks.vector_source_c(src_data2) - concatenate_signals = dab.concatenate_signals(gr.sizeof_gr_complex) - dst = blocks.vector_sink_c() - self.tb.connect(src0, (concatenate_signals,0)) - self.tb.connect(src1, (concatenate_signals,1)) - self.tb.connect(src2, (concatenate_signals,2)) - self.tb.connect(concatenate_signals, dst) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_result, result_data, 6) - - def test_002_concatenate_signals(self): - src_data0 = [6j] - src_data1 = [1j,2j,3j,4j,5j]*3000 - src_data2 = [7j] - src_data3 = [8j,9j,10j,11j]*3000 - expected_result = src_data0 + src_data1 + src_data2 + src_data3 - src0 = blocks.vector_source_c(src_data0) - src1 = blocks.vector_source_c(src_data1) - src2 = blocks.vector_source_c(src_data2) - src3 = blocks.vector_source_c(src_data3) - concatenate_signals = dab.concatenate_signals(gr.sizeof_gr_complex) - dst = blocks.vector_sink_c() - self.tb.connect(src0, (concatenate_signals,0)) - self.tb.connect(src1, (concatenate_signals,1)) - self.tb.connect(src2, (concatenate_signals,2)) - self.tb.connect(src3, (concatenate_signals,3)) - self.tb.connect(concatenate_signals, dst) - self.tb.run() - result_data = dst.data() - self.assertComplexTuplesAlmostEqual(expected_result, result_data, 6) - - def test_003_concatenate_signals(self): - src_data0 = [6] - src_data1 = [1,2,3,4,5] - src_data2 = [7] - src_data3 = [8,9,10,11] - expected_result = src_data0 + src_data1 + src_data2 + src_data3 - src0 = blocks.vector_source_b(src_data0) - src1 = blocks.vector_source_b(src_data1) - src2 = blocks.vector_source_b(src_data2) - src3 = blocks.vector_source_b(src_data3) - concatenate_signals = dab.concatenate_signals(gr.sizeof_char) - dst = blocks.vector_sink_b() - self.tb.connect(src0, (concatenate_signals,0)) - self.tb.connect(src1, (concatenate_signals,1)) - self.tb.connect(src2, (concatenate_signals,2)) - self.tb.connect(src3, (concatenate_signals,3)) - self.tb.connect(concatenate_signals, dst) - self.tb.run() - result_data = list(dst.data()) - self.assertEqual(expected_result, result_data) - -if __name__ == '__main__': - gr_unittest.main() - diff --git a/python/qa_conv_encoder_bb.py b/python/qa/qa_conv_encoder_bb.py similarity index 87% rename from python/qa_conv_encoder_bb.py rename to python/qa/qa_conv_encoder_bb.py index 6c8c439d..460a85ad 100755 --- a/python/qa_conv_encoder_bb.py +++ b/python/qa/qa_conv_encoder_bb.py @@ -25,6 +25,11 @@ import dab_swig as dab class qa_conv_encoder_bb (gr_unittest.TestCase): + """ + @brief QA for the convolutional encoder block + + This class implements a test bench to verify the corresponding C++ class. + """ def setUp (self): self.tb = gr.top_block () @@ -32,8 +37,10 @@ def setUp (self): def tearDown (self): self.tb = None -# test of a 2 byte frame with reference data (calculated by hand) def test_001_t(self): + """ + test of a 2 byte frame with reference data (calculated by hand) + """ data = (0x05, 0x00) expected_result = (0x00, 0x00, 0x0f, 0x62, 0xBF, 0x4D, 0x9F, 0x00, 0x00, 0x00, 0x00) src = blocks.vector_source_b(data) diff --git a/python/qa/qa_correct_individual_phase_offset_vff.py b/python/qa/qa_correct_individual_phase_offset_vff.py deleted file mode 100755 index 68afc261..00000000 --- a/python/qa/qa_correct_individual_phase_offset_vff.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gr_unittest -from gnuradio import blocks -from math import pi -import dab - -class qa_correct_individual_phase_offset_vff(gr_unittest.TestCase): - """ - @brief QA for the individual carrier phase equalisation block. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_correct_individual_phase_offset_vff(self): - expected_result = [x*pi/2+pi/4 for x in [1,-2,-1,0,1,-2]] - src_data = map(lambda x,y: x+y, expected_result,[0.1,0.3,-0.2,0.2,0.4,0.1]) - src = blocks.vector_source_f(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_float, 3) - mut = dab.correct_individual_phase_offset_vff(3, 1) - v2s = blocks.vector_to_stream(gr.sizeof_float, 3) - dst = blocks.vector_sink_f() - self.tb.connect(src, s2v, mut, v2s, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(expected_result, result_data, 5) - - def test_002_correct_individual_phase_offset_vff(self): - data = [x*pi/2+pi/4 for x in [1,-2,-1,0,1,-2]] - src_data = map(lambda x,y: x+y, data, [0.1,0.3,-0.4,0.2,0.4,0.1]) - expected_result = map(lambda x,y: x+y, data, [0.05,0.15,-0.2,0.075,0.125,0.15]) - src = blocks.vector_source_f(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_float, 3) - mut = dab.correct_individual_phase_offset_vff(3, 0.5) - v2s = blocks.vector_to_stream(gr.sizeof_float, 3) - dst = blocks.vector_sink_f() - self.tb.connect(src, s2v, mut, v2s, dst) - self.tb.run() - result_data = dst.data() - # print src_data - # print expected_result - # print result_data - self.assertFloatTuplesAlmostEqual(expected_result, result_data, 5) - -if __name__ == '__main__': - gr_unittest.main() - diff --git a/python/qa_crc16_bb.py b/python/qa/qa_crc16_bb.py similarity index 95% rename from python/qa_crc16_bb.py rename to python/qa/qa_crc16_bb.py index c7b807b3..be764eea 100755 --- a/python/qa_crc16_bb.py +++ b/python/qa/qa_crc16_bb.py @@ -25,6 +25,12 @@ class qa_crc16_bb(gr_unittest.TestCase): + """ + @brief QA for the crc16 block + + This class implements a test bench to verify the corresponding C++ class. + """ + def setUp(self): self.tb = gr.top_block() diff --git a/python/qa_dab_transmission_frame_mux_bb.py b/python/qa/qa_dab_transmission_frame_mux_bb.py similarity index 100% rename from python/qa_dab_transmission_frame_mux_bb.py rename to python/qa/qa_dab_transmission_frame_mux_bb.py diff --git a/python/qa_dabplus_audio_decoder_ff.py b/python/qa/qa_dabplus_audio_decoder_ff.py similarity index 100% rename from python/qa_dabplus_audio_decoder_ff.py rename to python/qa/qa_dabplus_audio_decoder_ff.py diff --git a/python/qa/qa_diff_phasor_vcc.py b/python/qa/qa_diff_phasor_vcc.py index 36cfbc42..6c53a33e 100755 --- a/python/qa/qa_diff_phasor_vcc.py +++ b/python/qa/qa_diff_phasor_vcc.py @@ -2,50 +2,50 @@ from gnuradio import gr, gr_unittest from gnuradio import blocks -import dab +import dab_swig as dab + class qa_diff_phasor_vcc(gr_unittest.TestCase): - """ - @brief QA for the phase differentiation block. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_diff_phasor_vcc(self): - a = [1+2j,2+3.5j,3.5+4j,4+5j,5+6j] - b = [1j,1j,1j,1j,1j] - c = [-1j+3,1j,-7+0j,2.5j+0.333,3.2j] - d = [(0.35979271051026462+0.89414454782483865j), - (0.19421665709046287+0.024219594550527801j), - (0.12445564785882557+0.40766238899138718j), - (0.041869638845043688+0.97860437393366329j), - (0.068927762235083234+0.16649764877365247j)] - e = [(0.16207552830286298+0.435385030608331j), - (0.47195779613669675+0.37824764113272558j), - (0.13911998015446148+0.6585095669811617j), - (0.093510743358783954+0.98446560079828938j), - (0.86036393297704694+0.72043005342024602j)] - multconj = lambda x,y: x.conjugate()*y - src_data = a+b+c+d+e - expected_result = [0j,0j,0j,0j,0j]+map(multconj,a,b)+map(multconj,b,c)+map(multconj,c,d)+map(multconj,d,e) - src = blocks.vector_source_c(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, 5) - diff_phasor_vcc = dab.diff_phasor_vcc(5) - v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, 5) - dst = blocks.vector_sink_c() - self.tb.connect(src, s2v, diff_phasor_vcc, v2s, dst) - self.tb.run() - result_data = dst.data() - # print expected_result - # print result_data - self.assertComplexTuplesAlmostEqual(expected_result, result_data, 6) + """ + @brief QA for the phase differentiation block. + + This class implements a test bench to verify the corresponding C++ class. + """ + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001_diff_phasor_vcc(self): + a = [1 + 2j, 2 + 3.5j, 3.5 + 4j, 4 + 5j, 5 + 6j] + b = [1j, 1j, 1j, 1j, 1j] + c = [-1j + 3, 1j, -7 + 0j, 2.5j + 0.333, 3.2j] + d = [(0.35979271051026462 + 0.89414454782483865j), + (0.19421665709046287 + 0.024219594550527801j), + (0.12445564785882557 + 0.40766238899138718j), + (0.041869638845043688 + 0.97860437393366329j), + (0.068927762235083234 + 0.16649764877365247j)] + e = [(0.16207552830286298 + 0.435385030608331j), + (0.47195779613669675 + 0.37824764113272558j), + (0.13911998015446148 + 0.6585095669811617j), + (0.093510743358783954 + 0.98446560079828938j), + (0.86036393297704694 + 0.72043005342024602j)] + multconj = lambda x, y: x.conjugate() * y + src_data = a + b + c + d + e + expected_result = [0j, 0j, 0j, 0j, 0j] + map(multconj, a, b) \ + + map(multconj, b, c) + map(multconj, c, d) + map(multconj, d, e) + src = blocks.vector_source_c(src_data) + s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, 5) + diff_phasor_vcc = dab.diff_phasor_vcc(5) + v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, 5) + dst = blocks.vector_sink_c() + self.tb.connect(src, s2v, diff_phasor_vcc, v2s, dst) + self.tb.run() + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 6) -if __name__ == '__main__': - gr_unittest.main() +if __name__ == '__main__': + gr_unittest.main() diff --git a/python/qa_energy_disp.py b/python/qa/qa_energy_disp.py similarity index 100% rename from python/qa_energy_disp.py rename to python/qa/qa_energy_disp.py diff --git a/python/qa_fib_sink_vb.py b/python/qa/qa_fib_sink_vb.py similarity index 88% rename from python/qa_fib_sink_vb.py rename to python/qa/qa_fib_sink_vb.py index 7af5c45c..1af8d69f 100644 --- a/python/qa_fib_sink_vb.py +++ b/python/qa/qa_fib_sink_vb.py @@ -24,6 +24,11 @@ import dab_swig as dab class qa_fib_sink_vb (gr_unittest.TestCase): + """ + @brief QA for the fib sink block + + This class implements a test bench to verify the corresponding C++ class. + """ def setUp (self): self.tb = gr.top_block () @@ -31,8 +36,10 @@ def setUp (self): def tearDown (self): self.tb = None -#manual check of print outs with reference data of debug file (SWR radio station) def test_001_t (self): + """ + manual check of print outs with reference data of debug file + """ data = ( 0x05, 0x00, 0x10, 0xEA, 0x04, 0x24, 0x06, 0x02, 0xD3, 0xA6, 0x01, 0x3F, 0x06, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x89) diff --git a/python/qa_fib_source_b.py b/python/qa/qa_fib_source_b.py similarity index 100% rename from python/qa_fib_source_b.py rename to python/qa/qa_fib_source_b.py diff --git a/python/qa_fic_encode.py b/python/qa/qa_fic_encode.py similarity index 87% rename from python/qa_fic_encode.py rename to python/qa/qa_fic_encode.py index adb43e42..1d2e66e8 100755 --- a/python/qa_fic_encode.py +++ b/python/qa/qa_fic_encode.py @@ -21,11 +21,10 @@ from gnuradio import gr, gr_unittest from gnuradio import blocks -from gnuradio import fec import dab_swig as dab from parameters import dab_parameters from fic_encode import fic_encode -from fic import fic_decode +from fic_decode_vc import fic_decode_vc as fic_decode class qa_fic_encode (gr_unittest.TestCase): @@ -50,28 +49,24 @@ def test_001_t (self): self.unpack = blocks.packed_to_unpacked_bb_make(1, gr.GR_MSB_FIRST) # mapper - self.map = dab.mapper_bc_make(self.dp.num_carriers) + self.s2v = blocks.stream_to_vector_make(gr.sizeof_char, self.dp.num_carriers/4) + self.map = dab.qpsk_mapper_vbvc_make(self.dp.num_carriers) # demapper - self.s2v = blocks.stream_to_vector_make(gr.sizeof_gr_complex, self.dp.num_carriers) self.soft_interleaver = dab.complex_to_interleaved_float_vcf_make(self.dp.num_carriers) # decode self.fic_decoder = fic_decode(self.dab_params) - # control stream - self.trigger_src = blocks.vector_source_b([1] + [0]*74, True) - self.tb.connect(self.fib_src, blocks.head_make(gr.sizeof_char, 100000), self.fib_enc, self.unpack, - self.map, self.s2v, + self.map, self.soft_interleaver, self.fic_decoder ) - self.tb.connect(self.trigger_src, (self.fic_decoder, 1)) self.tb.run () diff --git a/python/qa/qa_frequency_interleaver_vcc.py b/python/qa/qa_frequency_interleaver_vcc.py new file mode 100755 index 00000000..c21c62e4 --- /dev/null +++ b/python/qa/qa_frequency_interleaver_vcc.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +from gnuradio import gr, gr_unittest +from gnuradio import blocks +import dab_swig as dab + + +class qa_frequency_interleaver_vcc(gr_unittest.TestCase): + """ + @brief QA for frequency interleaving. + + This class implements a test bench to verify the corresponding C++ class. + """ + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001_frequency_interleaver_vcc(self): + src_data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9 + 1j] + expected_result = [2, 1, 4, 0, 3, 7, 6, 9 + 1j, 5, 8] + expected_result = [complex(x) for x in expected_result] + src = blocks.vector_source_c(src_data) + s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, 5) + frequency_interleaver_vcc = dab.frequency_interleaver_vcc([3, 1, 0, 4, 2]) + v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, 5) + dst = blocks.vector_sink_c() + self.tb.connect(src, s2v, frequency_interleaver_vcc, v2s, dst) + self.tb.run() + result_data = dst.data() + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 6) + + +if __name__ == '__main__': + gr_unittest.main() diff --git a/python/qa/qa_frequency_interleaving.py b/python/qa/qa_frequency_interleaving.py deleted file mode 100755 index 63f47c5c..00000000 --- a/python/qa/qa_frequency_interleaving.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gr_unittest -from gnuradio import blocks -import dab - -class qa_frequency_interleaver_vcc(gr_unittest.TestCase): - """ - @brief QA for frequency interleaving. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_frequency_interleaver_vcc(self): - src_data = [0,1,2,3,4,5,6,7,8,9+1j] - expected_result = [2,1,4,0,3,7,6,9+1j,5,8] - expected_result = [complex(x) for x in expected_result] - src = blocks.vector_source_c(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, 5) - frequency_interleaver_vcc = dab.frequency_interleaver_vcc([3,1,0,4,2]) - v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, 5) - dst = blocks.vector_sink_c() - self.tb.connect(src, s2v, frequency_interleaver_vcc, v2s, dst) - self.tb.run() - result_data = dst.data() - # print expected_result - # print result_data - self.assertComplexTuplesAlmostEqual(expected_result, result_data, 6) - -if __name__ == '__main__': - gr_unittest.main() - diff --git a/python/qa/qa_insert_null_symbol.py b/python/qa/qa_insert_null_symbol.py index 7ae8e01e..1d396b60 100755 --- a/python/qa/qa_insert_null_symbol.py +++ b/python/qa/qa_insert_null_symbol.py @@ -2,39 +2,40 @@ from gnuradio import gr, gr_unittest from gnuradio import blocks -import dab +import dab_swig as dab + class qa_insert_null_symbol(gr_unittest.TestCase): - """ - @brief QA for Null symbol insertion. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_insert_null_symbol(self): - src_data0 = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] - src_data1 = [0,1,0,1,0] - expected_result = [1,2,3,0,0,0,0,0,4,5,6,7,8,9,0,0,0,0,0,10,11,12,13,14,15] - expected_result = [complex(x) for x in expected_result] - src0 = blocks.vector_source_c(src_data0) - src1 = blocks.vector_source_b(src_data1) - s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, 3) - insert_null_symbol = dab.insert_null_symbol(5,3) - dst = blocks.vector_sink_c() - self.tb.connect(src0, s2v, insert_null_symbol, dst) - self.tb.connect(src1, (insert_null_symbol,1)) - self.tb.run() - result_data = dst.data() - # print expected_result - # print result_data - self.assertComplexTuplesAlmostEqual(expected_result, result_data, 6) + """ + @brief QA for Null symbol insertion. + + This class implements a test bench to verify the corresponding C++ class. + """ + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001_insert_null_symbol(self): + src_data0 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + src_data1 = [0, 1, 0, 1, 0] + expected_result = [1, 2, 3, 0, 0, 0, 0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15] + expected_result = [complex(x) for x in expected_result] + src0 = blocks.vector_source_c(src_data0) + src1 = blocks.vector_source_b(src_data1) + s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, 3) + insert_null_symbol = dab.insert_null_symbol(5, 3) + dst = blocks.vector_sink_c() + self.tb.connect(src0, s2v, insert_null_symbol, dst) + self.tb.connect(src1, (insert_null_symbol, 1)) + self.tb.run() + result_data = dst.data() + # print expected_result + # print result_data + self.assertComplexTuplesAlmostEqual(expected_result, result_data, 6) -if __name__ == '__main__': - gr_unittest.main() +if __name__ == '__main__': + gr_unittest.main() diff --git a/python/qa_mp2_decode_bs.py b/python/qa/qa_mp2_decode_bs.py similarity index 100% rename from python/qa_mp2_decode_bs.py rename to python/qa/qa_mp2_decode_bs.py diff --git a/python/qa_mp2_encode_sb.py b/python/qa/qa_mp2_encode_sb.py similarity index 100% rename from python/qa_mp2_encode_sb.py rename to python/qa/qa_mp2_encode_sb.py diff --git a/python/qa_mp4_decode_bs.py b/python/qa/qa_mp4_decode_bs.py similarity index 94% rename from python/qa_mp4_decode_bs.py rename to python/qa/qa_mp4_decode_bs.py index 3819815e..f0b00359 100755 --- a/python/qa_mp4_decode_bs.py +++ b/python/qa/qa_mp4_decode_bs.py @@ -26,6 +26,11 @@ import dab_swig as dab class qa_mp4_decode_bs (gr_unittest.TestCase): + """ + @brief QA for the mp4 decode block + + This class implements a test bench to verify the corresponding C++ class. + """ def setUp (self): self.tb = gr.top_block () diff --git a/python/qa_mp4_encode_sb.py b/python/qa/qa_mp4_encode_sb.py similarity index 100% rename from python/qa_mp4_encode_sb.py rename to python/qa/qa_mp4_encode_sb.py diff --git a/python/qa_msc_decode.py b/python/qa/qa_msc_decode.py similarity index 100% rename from python/qa_msc_decode.py rename to python/qa/qa_msc_decode.py diff --git a/python/qa_msc_encode.py b/python/qa/qa_msc_encode.py similarity index 100% rename from python/qa_msc_encode.py rename to python/qa/qa_msc_encode.py diff --git a/python/qa/qa_ofdm_coarse_frequency_correct.py b/python/qa/qa_ofdm_coarse_frequency_correct.py deleted file mode 100755 index c1f106d9..00000000 --- a/python/qa/qa_ofdm_coarse_frequency_correct.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gr_unittest -from gnuradio import blocks -import dab -import cmath - -class qa_ofdm_coarse_frequency_correct(gr_unittest.TestCase): - """ - @brief QA for the coarse frequency correction class. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_ofdm_coarse_frequency_correct(self): - fft_length = 10 - num_carriers = 2 - cp_length = 3 - src_data0 = [0,1,2,3,4,5,6,7,8,9,1,2,0,5,7,6,0,4,0,6,1,1,1,0.8,0.1,1.3,1,0.7,1,1,0,1,2,3,4,5,6,7,8,9] - expected_result0 = [7,9,5,6,0.8,1.3,3,5] - offset = [3,3,-1,-1,-1,-1,-1,-1] - frame_index = [0,0, 0, 0, 0, 0, 1, 1] - expected_result0 = [complex(expected_result0[i])*cmath.exp(-2j*cmath.pi*offset[i]*cp_length/float(fft_length)*frame_index[i]) for i in range(0,8)] - src_data1 = [1,1,1,0] - expected_result1 = (1,1,1,0) - src0 = blocks.vector_source_c(src_data0) - src1 = blocks.vector_source_b(src_data1) - s2v0 = blocks.stream_to_vector(gr.sizeof_gr_complex, fft_length) - ofdm_coarse_frequency_correct = dab.ofdm_coarse_frequency_correct(fft_length,num_carriers,cp_length) - v2s0 = blocks.vector_to_stream(gr.sizeof_gr_complex, num_carriers) - dst0 = blocks.vector_sink_c() - dst1 = blocks.vector_sink_b() - self.tb.connect(src0, s2v0, (ofdm_coarse_frequency_correct,0)) - self.tb.connect(src1, (ofdm_coarse_frequency_correct,1)) - self.tb.connect((ofdm_coarse_frequency_correct,0), v2s0, dst0) - self.tb.connect((ofdm_coarse_frequency_correct,1), dst1) - self.tb.run() - result_data0 = dst0.data() - result_data1 = dst1.data() - # print expected_result0 - # print result_data0 - self.assertComplexTuplesAlmostEqual(expected_result0, result_data0, 4) - self.assertEqual(result_data1, expected_result1) - -if __name__ == '__main__': - gr_unittest.main() - diff --git a/python/qa/qa_ofdm_ffe_all_in_one.py b/python/qa/qa_ofdm_ffe_all_in_one.py deleted file mode 100755 index c6647f06..00000000 --- a/python/qa/qa_ofdm_ffe_all_in_one.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gr_unittest -from gnuradio import blocks -import dab -import cmath -from math import pi - -class qa_ofdm_ffs_sample(gr_unittest.TestCase): - """ - @brief Module test for the OFDM ffs sampler with phase calculation. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_ofdm_ffe_all_in_one(self): - symbol_length = 5 - num_symbols = 2 - fft_length = 3 - alpha = 0.1 - src_data0 = [77*cmath.exp(2j*pi*x/20) for x in range(0,20)] - src_data0[4] = 100 # should not matter, as this area of the symbol is not evaluated - src_data0[12:19] = [100] * 7 # should not matter, as only the first two symbols are evaluated - src_data1 = (0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) - d = -2*pi/20 # phase diff between two consective samples - expected_result = (0,0,0,0,0,0,0,0,0,0,0,0,d,d,d,d,d,d,d,d) - src0 = blocks.vector_source_c(src_data0) - src1 = blocks.vector_source_b(src_data1) - ffe = dab.ofdm_ffe_all_in_one(symbol_length, fft_length, num_symbols, alpha, 10) - dst0 = blocks.vector_sink_f() - self.tb.connect(src0, (ffe,0)) - self.tb.connect(src1, (ffe,1)) - self.tb.connect(ffe, dst0) - self.tb.run() - result_data0 = dst0.data() - # print expected_result - # print result_data0 - self.assertFloatTuplesAlmostEqual(expected_result, result_data0, 3) - -if __name__ == '__main__': - gr_unittest.main() - diff --git a/python/qa/qa_ofdm_insert_pilot.py b/python/qa/qa_ofdm_insert_pilot.py index 0dc2d39d..c415b4ad 100755 --- a/python/qa/qa_ofdm_insert_pilot.py +++ b/python/qa/qa_ofdm_insert_pilot.py @@ -1,45 +1,46 @@ #!/usr/bin/env python from gnuradio import gr, gr_unittest, blocks -import dab +import dab_swig as dab + class qa_ofdm_insert_pilot_vcc(gr_unittest.TestCase): - """ - @brief Module test for the class that inserts the pilot symbol. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_ofdm_insert_pilot_vcc(self): - pilot = [1j,2] - src_data0 = (0,1,2,3,4,5,6,7,8,9,0,1,2,3) - src_data1 = (1,0,0,1,0,1,0) - expected_result0 = (1j,2,0,1,2,3,4,5,1j,2,6,7,8,9,1j,2,0,1,2,3) - expected_result0 = [x+0j for x in expected_result0] - expected_result1 = (1,0,0,0,1,0,0,1,0,0) - src0 = blocks.vector_source_c(src_data0) - src1 = blocks.vector_source_b(src_data1) - s2v0 = blocks.stream_to_vector(gr.sizeof_gr_complex,2) - ofdm_insert_pilot = dab.ofdm_insert_pilot_vcc(pilot) - v2s0 = blocks.vector_to_stream(gr.sizeof_gr_complex,2) - dst0 = blocks.vector_sink_c() - dst1 = blocks.vector_sink_b() - self.tb.connect(src0, s2v0, (ofdm_insert_pilot,0)) - self.tb.connect(src1, (ofdm_insert_pilot,1)) - self.tb.connect((ofdm_insert_pilot,0), v2s0, dst0) - self.tb.connect((ofdm_insert_pilot,1), dst1) - self.tb.run() - result_data0 = dst0.data() - result_data1 = dst1.data() - self.assertComplexTuplesAlmostEqual(expected_result0, result_data0, 6) - self.assertEqual(result_data1, expected_result1) + """ + @brief Module test for the class that inserts the pilot symbol. + + This class implements a test bench to verify the corresponding C++ class. + """ + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001_ofdm_insert_pilot_vcc(self): + pilot = [1j, 2] + src_data0 = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3) + src_data1 = (1, 0, 0, 1, 0, 1, 0) + expected_result0 = (1j, 2, 0, 1, 2, 3, 4, 5, 1j, 2, 6, 7, 8, 9, 1j, 2, 0, 1, 2, 3) + expected_result0 = [x + 0j for x in expected_result0] + expected_result1 = (1, 0, 0, 0, 1, 0, 0, 1, 0, 0) + src0 = blocks.vector_source_c(src_data0) + src1 = blocks.vector_source_b(src_data1) + s2v0 = blocks.stream_to_vector(gr.sizeof_gr_complex, 2) + ofdm_insert_pilot = dab.ofdm_insert_pilot_vcc(pilot) + v2s0 = blocks.vector_to_stream(gr.sizeof_gr_complex, 2) + dst0 = blocks.vector_sink_c() + dst1 = blocks.vector_sink_b() + self.tb.connect(src0, s2v0, (ofdm_insert_pilot, 0)) + self.tb.connect(src1, (ofdm_insert_pilot, 1)) + self.tb.connect((ofdm_insert_pilot, 0), v2s0, dst0) + self.tb.connect((ofdm_insert_pilot, 1), dst1) + self.tb.run() + result_data0 = dst0.data() + result_data1 = dst1.data() + self.assertComplexTuplesAlmostEqual(expected_result0, result_data0, 6) + self.assertEqual(result_data1, expected_result1) -if __name__ == '__main__': - gr_unittest.main() +if __name__ == '__main__': + gr_unittest.main() diff --git a/python/qa/qa_ofdm_move_and_insert_zero.py b/python/qa/qa_ofdm_move_and_insert_zero.py index 60c95b38..6ec89a9b 100755 --- a/python/qa/qa_ofdm_move_and_insert_zero.py +++ b/python/qa/qa_ofdm_move_and_insert_zero.py @@ -1,40 +1,41 @@ #!/usr/bin/env python from gnuradio import gr, gr_unittest, blocks -import dab +import dab_swig as dab + class qa_ofdm_move_and_insert_zero(gr_unittest.TestCase): - """ - @brief QA for the block that moves the signal to the middle of the band and inserts the zero carrier in the middle. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_ofdm_move_and_insert_zero(self): - num_carriers = 4 - fft_length = 10 - d_zeros_on_left = 3 - src_data0 = range(0,8) - expected_result0 = [0,0,0]+[0,1]+[0]+[2,3]+[0,0]+[0,0,0]+[4,5]+[0]+[6,7]+[0,0] - expected_result0 = [complex(x) for x in expected_result0] - src0 = blocks.vector_source_c(src_data0) - s2v0 = blocks.stream_to_vector(gr.sizeof_gr_complex, num_carriers) - ofdm_move_and_insert_zero = dab.ofdm_move_and_insert_zero(fft_length,num_carriers) - v2s0 = blocks.vector_to_stream(gr.sizeof_gr_complex, fft_length) - dst0 = blocks.vector_sink_c() - self.tb.connect(src0, s2v0, ofdm_move_and_insert_zero, v2s0, dst0) - self.tb.run() - result_data0 = dst0.data() - # print expected_result0 - # print result_data0 - self.assertComplexTuplesAlmostEqual(expected_result0, result_data0, 6) + """ + @brief QA for the block that moves the signal to the middle of the band and inserts the zero carrier in the middle. + + This class implements a test bench to verify the corresponding C++ class. + """ + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001_ofdm_move_and_insert_zero(self): + num_carriers = 4 + fft_length = 10 + d_zeros_on_left = 3 + src_data0 = range(0, 8) + expected_result0 = [0, 0, 0] + [0, 1] + [0] + [2, 3] + [0, 0] + [0, 0, 0] + [4, 5] + [0] + [6, 7] + [0, 0] + expected_result0 = [complex(x) for x in expected_result0] + src0 = blocks.vector_source_c(src_data0) + s2v0 = blocks.stream_to_vector(gr.sizeof_gr_complex, num_carriers) + ofdm_move_and_insert_zero = dab.ofdm_move_and_insert_zero(fft_length, num_carriers) + v2s0 = blocks.vector_to_stream(gr.sizeof_gr_complex, fft_length) + dst0 = blocks.vector_sink_c() + self.tb.connect(src0, s2v0, ofdm_move_and_insert_zero, v2s0, dst0) + self.tb.run() + result_data0 = dst0.data() + # print expected_result0 + # print result_data0 + self.assertComplexTuplesAlmostEqual(expected_result0, result_data0, 6) -if __name__ == '__main__': - gr_unittest.main() +if __name__ == '__main__': + gr_unittest.main() diff --git a/python/qa_prune.py b/python/qa/qa_prune.py similarity index 92% rename from python/qa_prune.py rename to python/qa/qa_prune.py index b2032bf4..aeecd5ec 100755 --- a/python/qa_prune.py +++ b/python/qa/qa_prune.py @@ -24,6 +24,11 @@ import dab_swig as dab class qa_prune (gr_unittest.TestCase): + """ + @brief QA for the prune block + + This class implements a test bench to verify the corresponding C++ class. + """ def setUp (self): self.tb = gr.top_block () @@ -40,7 +45,6 @@ def test_001_prune(self): self.tb.connect(src, prune, dst) self.tb.run() result_data = dst.data() - # print result_data self.assertFloatTuplesAlmostEqual(expected_result, result_data, 6) diff --git a/python/qa/qa_prune_vectors.py b/python/qa/qa_prune_vectors.py deleted file mode 100755 index 740aa931..00000000 --- a/python/qa/qa_prune_vectors.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gr_unittest, blocks -import dab - -class qa_prune_vectors(gr_unittest.TestCase): - """ - @brief QA for the vector pruning block. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_prune_vectors(self): - src_data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] - expected_result = [3,4,8,9,13,14] - src = blocks.vector_source_f(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_float, 5) - prune_vectors = dab.prune_vectors(gr.sizeof_float,5,2,1) - v2s = blocks.vector_to_stream(gr.sizeof_float, 2) - dst = blocks.vector_sink_f() - self.tb.connect(src, s2v, prune_vectors, v2s, dst) - self.tb.run() - result_data = dst.data() - # print expected_result - # print result_data - self.assertFloatTuplesAlmostEqual(expected_result, result_data, 6) - - def test_002_prune_vectors(self): - src_data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] - expected_result = [3,4,8,9,13,14] - src = blocks.vector_source_b(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_char, 5) - prune_vectors = dab.prune_vectors(gr.sizeof_char,5,2,1) - v2s = blocks.vector_to_stream(gr.sizeof_char, 2) - dst = blocks.vector_sink_b() - self.tb.connect(src, s2v, prune_vectors, v2s, dst) - self.tb.run() - result_data = dst.data() - # print expected_result - # print result_data - self.assertFloatTuplesAlmostEqual(expected_result, result_data, 6) - -if __name__ == '__main__': - gr_unittest.main() - diff --git a/python/qa_puncture_bb.py b/python/qa/qa_puncture_bb.py similarity index 94% rename from python/qa_puncture_bb.py rename to python/qa/qa_puncture_bb.py index 3902320e..3f734cf7 100755 --- a/python/qa_puncture_bb.py +++ b/python/qa/qa_puncture_bb.py @@ -24,6 +24,11 @@ import dab_swig as dab class qa_puncture_bb (gr_unittest.TestCase): + """ + @brief QA for the puncture block + + This class implements a test bench to verify the corresponding C++ class. + """ def setUp (self): self.tb = gr.top_block () diff --git a/python/qa/qa_puncture_vbb.py b/python/qa/qa_puncture_vbb.py deleted file mode 100755 index fd518edf..00000000 --- a/python/qa/qa_puncture_vbb.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gr_unittest, blocks -import dab -import cmath - -class qa_puncture_vbb(gr_unittest.TestCase): - """ - @brief QA for the puncturing block. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_puncture_vbb(self): - src_data = (0,77,78,78,1,80,2,3,4,5,81,82,83,6,84,7,8,9) - punc_seq = (1,0,0,0,1,0,1,1,1) - exp_res = (0,1,2,3,4,5,6,7,8,9) - src = blocks.vector_source_b(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_char, 9) - puncture_vbb = dab.puncture_vbb(punc_seq) - v2s = blocks.vector_to_stream(gr.sizeof_char, 5) - dst = blocks.vector_sink_b() - self.tb.connect(src, s2v, puncture_vbb, v2s, dst) - self.tb.run() - result_data = dst.data() - self.assertEqual(exp_res, result_data) - - -if __name__ == '__main__': - gr_unittest.main() - diff --git a/python/qa/qa_qpsk_demapper_vcb.py b/python/qa/qa_qpsk_demapper_vcb.py deleted file mode 100755 index 4f2abd26..00000000 --- a/python/qa/qa_qpsk_demapper_vcb.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gr_unittest, blocks -import dab - -class qa_qpsk_demapper_vcb(gr_unittest.TestCase): - """ - @brief QA for the QPSK demapper. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_qpsk_demapper_vcb(self): - src_data = [1+2j,3+1j,-1+1j,-1+1j,-0.0001+1000j,1+1j,1+1j,1+1j] - expected_result = (10,128) - src = blocks.vector_source_c(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_gr_complex, 4) - qpsk_demapper_vcb = dab.qpsk_demapper_vcb(4) - v2s = blocks.vector_to_stream(gr.sizeof_char, 1) - dst = blocks.vector_sink_b() - self.tb.connect(src, s2v, qpsk_demapper_vcb, v2s, dst) - self.tb.run() - result_data = dst.data() - # print expected_result - # print result_data - self.assertEqual(expected_result, result_data) - -if __name__ == '__main__': - gr_unittest.main() - diff --git a/python/qa/qa_qpsk_mapper_vbc.py b/python/qa/qa_qpsk_mapper_vbc.py deleted file mode 100755 index 857fea4d..00000000 --- a/python/qa/qa_qpsk_mapper_vbc.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gr_unittest, blocks -import dab -import math - -class qa_qpsk_mapper_vbc(gr_unittest.TestCase): - """ - @brief QA for the QPSK mapper. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_qpsk_mapper_vbc(self): - src_data = [10,128] - expected_result = [1+1j,1+1j,-1+1j,-1+1j,-1+1j,1+1j,1+1j,1+1j] - expected_result = [x/math.sqrt(2) for x in expected_result] - src = blocks.vector_source_b(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_char, 1) - qpsk_mapper_vbc = dab.qpsk_mapper_vbc(4) - v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, 4) - dst = blocks.vector_sink_c() - self.tb.connect(src, s2v, qpsk_mapper_vbc, v2s, dst) - self.tb.run() - result_data = dst.data() - # print expected_result - # print result_data - self.assertComplexTuplesAlmostEqual(expected_result, result_data, 6) - -if __name__ == '__main__': - gr_unittest.main() - diff --git a/python/qa/qa_qpsk_mapper_vbvc.py b/python/qa/qa_qpsk_mapper_vbvc.py new file mode 100644 index 00000000..104d8fb6 --- /dev/null +++ b/python/qa/qa_qpsk_mapper_vbvc.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). +# +# 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. +# + +from gnuradio import gr, gr_unittest +from gnuradio import blocks +import math +import dab_swig as dab + + +class qa_qpsk_mapper_vbvc(gr_unittest.TestCase): + """ + @brief QA for the qpsk mapper block + + This class implements a test bench to verify the corresponding C++ class. + """ + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + + def test_001_qpsk_mapper_vbvc(self): + src_data = (31, 255) + vector_length = 8 + SQRT2 = 1.0/math.sqrt(2) + expected_result = (SQRT2 - SQRT2*1j, SQRT2 - SQRT2*1j, SQRT2 - SQRT2*1j, -SQRT2 - SQRT2*1j, -SQRT2 - SQRT2*1j, + -SQRT2 - SQRT2*1j, -SQRT2 - SQRT2*1j, -SQRT2 - SQRT2*1j) + src = blocks.vector_source_b(src_data) + s2v = blocks.stream_to_vector(gr.sizeof_char, vector_length/4) + mapper = dab.qpsk_mapper_vbvc_make(vector_length) + v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, vector_length) + dst = blocks.vector_sink_c() + self.tb.connect(src, s2v, mapper, v2s, dst) + self.tb.run() + result_data = dst.data() + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 6) + + def test_002_qpsk_mapper_vbvc(self): + src_data = (0, 3) + vector_length = 8 + SQRT2 = 1.0/math.sqrt(2) + expected_result = (SQRT2 + SQRT2*1j, SQRT2 + SQRT2*1j, SQRT2 + SQRT2*1j, SQRT2 + SQRT2*1j, SQRT2 + SQRT2*1j, + SQRT2 + SQRT2*1j, SQRT2 - SQRT2*1j, SQRT2 - SQRT2*1j) + src = blocks.vector_source_b(src_data) + s2v = blocks.stream_to_vector(gr.sizeof_char, vector_length/4) + mapper = dab.qpsk_mapper_vbvc_make(vector_length) + v2s = blocks.vector_to_stream(gr.sizeof_gr_complex, vector_length) + dst = blocks.vector_sink_c() + self.tb.connect(src, s2v, mapper, v2s, dst) + self.tb.run() + result_data = dst.data() + self.assertFloatTuplesAlmostEqual(expected_result, result_data, 6) + + +if __name__ == '__main__': + gr_unittest.run(qa_qpsk_mapper_vbvc, "qa_qpsk_mapper_vbvc.xml") \ No newline at end of file diff --git a/python/qa_reed_solomon_decode_bb.py b/python/qa/qa_reed_solomon_decode_bb.py similarity index 95% rename from python/qa_reed_solomon_decode_bb.py rename to python/qa/qa_reed_solomon_decode_bb.py index 15945071..c59185d9 100755 --- a/python/qa_reed_solomon_decode_bb.py +++ b/python/qa/qa_reed_solomon_decode_bb.py @@ -32,8 +32,10 @@ def setUp (self): def tearDown (self): self.tb = None -# insert 5 errors in rs-encoded prbs reference sequence and correct them with rs_decoder def test_001_t(self): + """ + insert 5 errors in rs-encoded prbs reference and correct them with rs_decoder + """ self.prbs = ( 154, 15, 22, 223, 146, 92, 238, 15, 39, 87, 230, 120, 80, 186, 147, 176, 169, 49, 253, 117, 245, 122, 30, 187, 74, 141, 148, 1, 181, 10, 0, 244, 250, 199, 227, 56, 155, 105, 187, 219, 135, 61, 241, 87, 223, 75, 59, 112, 78, @@ -47,7 +49,7 @@ def test_001_t(self): 241, 87, 223, 75, 59, 112, 78, 238, 63, 69, 246, 177, 92, 140, 117, 34, 254, 70, 18, 131, 116, 13, 51, 174, 239, 86, 135, 157, 180, 97, 156, 48, 179, 190, 218, 99, 171, 29, 49, 42, 78, 63, 3, 7, 3, 145, 60, 180, 134, 27, 104, 230, 32, 171, 6, 109, 106, 1, 6, 45, 104, - 206, 138, 38, 107, 242, 128, 228, 215, 34, 43, 109, 122, 92, 195, 54, 105, 246L) + 206, 138, 38, 107, 242, 128, 228, 215, 34, 43, 109, 122, 92, 195, 54, 105, 246) self.src = blocks.vector_source_b(self.corrupted_data) self.rs_decoder = dab.reed_solomon_decode_bb_make(1) diff --git a/python/qa_reed_solomon_encode_bb.py b/python/qa/qa_reed_solomon_encode_bb.py similarity index 92% rename from python/qa_reed_solomon_encode_bb.py rename to python/qa/qa_reed_solomon_encode_bb.py index af2c16d2..bcf619ec 100755 --- a/python/qa_reed_solomon_encode_bb.py +++ b/python/qa/qa_reed_solomon_encode_bb.py @@ -21,21 +21,26 @@ from gnuradio import gr, gr_unittest from gnuradio import blocks -import random import dab_swig as dab class qa_reed_solomon_encode_bb(gr_unittest.TestCase): + """ + @brief QA for the reed solomon encode block + + This class implements a test bench to verify the corresponding C++ class. + """ + def setUp(self): self.tb = gr.top_block() def tearDown(self): self.tb = None - # test_001 encode prbs sequence and check with reference data - # test_002 insert 5 errors in rs-encoded prbs reference sequence and correct them with rs_decoder - def test_001_t(self): + """ + encode prbs sequence and check with reference data + """ self.prbs = ( 154, 15, 22, 223, 146, 92, 238, 15, 39, 87, 230, 120, 80, 186, 147, 176, 169, 49, 253, 117, 245, 122, 30, 187, 74, 141, 148, 1, 181, 10, 0, 244, 250, 199, 227, 56, 155, 105, 187, 219, 135, 61, 241, 87, 223, 75, 59, 112, 78, @@ -61,6 +66,9 @@ def test_001_t(self): def test_002_t(self): + """ + insert 5 errors in rs-encoded prbs reference sequence and correct them with rs_decoder + """ self.prbs = ( 154, 15, 22, 223, 146, 92, 238, 15, 39, 87, 230, 120, 80, 186, 147, 176, 169, 49, 253, 117, 245, 122, 30, 187, 74, 141, 148, 1, 181, 10, 0, 244, 250, 199, 227, 56, 155, 105, 187, 219, 135, 61, 241, 87, 223, 75, 59, 112, 78, diff --git a/python/qa_mapper_bc.py b/python/qa/qa_select_cus_vfvf.py old mode 100755 new mode 100644 similarity index 50% rename from python/qa_mapper_bc.py rename to python/qa/qa_select_cus_vfvf.py index 434b4f25..f150c484 --- a/python/qa_mapper_bc.py +++ b/python/qa/qa_select_cus_vfvf.py @@ -1,30 +1,34 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# -# Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). -# +# +# Copyright 2018 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). +# # 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. -# +# from gnuradio import gr, gr_unittest from gnuradio import blocks -import dab_swig as dab -from math import sqrt +import dab -class qa_mapper_bc (gr_unittest.TestCase): +class qa_select_cus_vfvf (gr_unittest.TestCase): + """ + @brief QA for the select cus block + + This class implements a test bench to verify the corresponding C++ class. + """ def setUp (self): self.tb = gr.top_block () @@ -32,20 +36,20 @@ def setUp (self): def tearDown (self): self.tb = None - def test_001_mapper_bc(self): - data = (1, 0, 1, 0, 1, 1, 0, 0) - expected_result = (-1 - 1j, 1 - 1j, -1 + 1j, 1 + 1j) - expected_result = [x / sqrt(2) for x in expected_result] - src = blocks.vector_source_b_make(data) - map = dab.mapper_bc_make(4) - dst = blocks.vector_sink_c() - self.tb.connect(src, map, dst) + def test_001_t(self): + vector01 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) + expected_result = (1, 2, 3, 4, 9, 10, 11, 12) + src = blocks.vector_source_b(vector01, True) + b2f = blocks.char_to_float_make() + s2v = blocks.stream_to_vector_make(gr.sizeof_float, 4) + select_cus = dab.select_cus_vfvf_make(4, 2, 0, 1) + v2s = blocks.vector_to_stream_make(gr.sizeof_float, 4) + dst = blocks.vector_sink_f() + self.tb.connect(src, b2f, s2v, select_cus, blocks.head_make(gr.sizeof_float*4, 2), v2s, dst) self.tb.run() - result_data = dst.data() - #print expected_result - #print result_data - self.assertComplexTuplesAlmostEqual(expected_result, result_data, 6) - + result = dst.data() + print result + self.assertEqual(expected_result, result) if __name__ == '__main__': - gr_unittest.run(qa_mapper_bc, "qa_mapper_bc.xml") + gr_unittest.run(qa_select_cus_vfvf, "qa_select_cus_vfvf.xml") diff --git a/python/qa/qa_select_vectors.py b/python/qa/qa_select_vectors.py deleted file mode 100755 index 36c7a610..00000000 --- a/python/qa/qa_select_vectors.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gr_unittest, blocks -import dab - -class qa_select_vectors(gr_unittest.TestCase): - """ - @brief QA for the vector select block - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_select_vectors(self): - skip = 2 - len = 3 - vlen = 2 - src_data = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7,8,9) - trig = (0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0) - expected_data = (6,7,8,9,10,11,6,7,8,9) - expected_trig = (1, 0, 0, 1, 0) - src = blocks.vector_source_b(src_data) - trigsrc = blocks.vector_source_b(trig) - s2v = blocks.stream_to_vector(gr.sizeof_char, 2) - select_vectors = dab.select_vectors(gr.sizeof_char,vlen,len,skip) - v2s = blocks.vector_to_stream(gr.sizeof_char, 2) - dst = blocks.vector_sink_b() - trigdst = blocks.vector_sink_b() - self.tb.connect(src, s2v, select_vectors, v2s, dst) - self.tb.connect(trigsrc, (select_vectors,1), trigdst) - self.tb.run() - result_data = dst.data() - result_trig = trigdst.data() - # print expected_result - # print result_data - self.assertEqual(expected_data, result_data) - self.assertEqual(expected_trig, result_trig) - - def test_002_select_vectors(self): - skip = 2 - len = 3 - vlen = 2 - src_data = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7,8,9) - trig = (0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0) - expected_data = (6,7,8,9,10,11,6,7,8,9) - expected_trig = (1, 0, 0, 1, 0) - src = blocks.vector_source_f(src_data) - trigsrc = blocks.vector_source_b(trig) - s2v = blocks.stream_to_vector(gr.sizeof_float, 2) - select_vectors = dab.select_vectors(gr.sizeof_float,vlen,len,skip) - v2s = blocks.vector_to_stream(gr.sizeof_float, 2) - dst = blocks.vector_sink_f() - trigdst = blocks.vector_sink_b() - self.tb.connect(src, s2v, select_vectors, v2s, dst) - self.tb.connect(trigsrc, (select_vectors,1), trigdst) - self.tb.run() - result_data = dst.data() - result_trig = trigdst.data() - # print expected_result - # print result_data - self.assertFloatTuplesAlmostEqual(expected_data, result_data) - self.assertEqual(expected_trig, result_trig) - -if __name__ == '__main__': - gr_unittest.main() - diff --git a/python/qa/qa_sum_phasor_trig_vcc.py b/python/qa/qa_sum_phasor_trig_vcc.py index aaeb7cd6..6ee5aa78 100755 --- a/python/qa/qa_sum_phasor_trig_vcc.py +++ b/python/qa/qa_sum_phasor_trig_vcc.py @@ -1,67 +1,69 @@ #!/usr/bin/env python from gnuradio import gr, gr_unittest, blocks -import dab +import dab_swig as dab + class qa_sum_phasor_trig_vcc(gr_unittest.TestCase): - """ - @brief QA for the phase summation class. + """ + @brief QA for the phase summation class. - This class implements a test bench to verify the corresponding C++ class. - """ + This class implements a test bench to verify the corresponding C++ class. + """ - def setUp(self): - self.tb = gr.top_block() + def setUp(self): + self.tb = gr.top_block() - def tearDown(self): - self.tb = None + def tearDown(self): + self.tb = None - def test_001_sum_phasor_trig_vcc(self): - src_data0 = (1,1j,1,1j,1j,1j,-1, 1j, 1,1j,1,1j) - src_data1 = (0, 1, 0, 0, 1, 0) - expected_result0 = (0,0, 1,1j,1j,-1,-1j,-1j,1,1j,1,-1) - expected_result0 = [x+0j for x in expected_result0] - src0 = blocks.vector_source_c(src_data0) - src1 = blocks.vector_source_b(src_data1) - s2v0 = blocks.stream_to_vector(gr.sizeof_gr_complex,2) - sum_phasor_trig_vcc = dab.sum_phasor_trig_vcc(2) - v2s0 = blocks.vector_to_stream(gr.sizeof_gr_complex,2) - dst0 = blocks.vector_sink_c() - dst1 = blocks.vector_sink_b() - self.tb.connect(src0, s2v0, (sum_phasor_trig_vcc,0)) - self.tb.connect(src1, (sum_phasor_trig_vcc,1)) - self.tb.connect((sum_phasor_trig_vcc,0), v2s0, dst0) - self.tb.connect((sum_phasor_trig_vcc,1), dst1) - self.tb.run() - result_data0 = dst0.data() - result_data1 = dst1.data() - # print expected_result0 - # print result_data0 - self.assertComplexTuplesAlmostEqual(expected_result0, result_data0, 6) - self.assertEqual(result_data1, src_data1) + def test_001_sum_phasor_trig_vcc(self): + src_data0 = (1, 1j, 1, 1j, 1j, 1j, -1, 1j, 1, 1j, 1, 1j) + src_data1 = (0, 1, 0, 0, 1, 0) + expected_result0 = (0, 0, 1, 1j, 1j, -1, -1j, -1j, 1, 1j, 1, -1) + expected_result0 = [x + 0j for x in expected_result0] + src0 = blocks.vector_source_c(src_data0) + src1 = blocks.vector_source_b(src_data1) + s2v0 = blocks.stream_to_vector(gr.sizeof_gr_complex, 2) + sum_phasor_trig_vcc = dab.sum_phasor_trig_vcc(2) + v2s0 = blocks.vector_to_stream(gr.sizeof_gr_complex, 2) + dst0 = blocks.vector_sink_c() + dst1 = blocks.vector_sink_b() + self.tb.connect(src0, s2v0, (sum_phasor_trig_vcc, 0)) + self.tb.connect(src1, (sum_phasor_trig_vcc, 1)) + self.tb.connect((sum_phasor_trig_vcc, 0), v2s0, dst0) + self.tb.connect((sum_phasor_trig_vcc, 1), dst1) + self.tb.run() + result_data0 = dst0.data() + result_data1 = dst1.data() + # print expected_result0 + # print result_data0 + self.assertComplexTuplesAlmostEqual(expected_result0, result_data0, 6) + self.assertEqual(result_data1, src_data1) - def test_002_sum_phasor_trig_vcc(self): - src_data0 = (1,1j,-1,1,1)*50 # try it multiple times to decect problems when leaving the function in between - src_data1 = (1,0,0,1,0)*50 - expected_result0 = (1,1j,-1j,1,1)*50 - expected_result0 = [x+0j for x in expected_result0] - src0 = blocks.vector_source_c(src_data0) - src1 = blocks.vector_source_b(src_data1) - s2v0 = blocks.stream_to_vector(gr.sizeof_gr_complex,1) - sum_phasor_trig_vcc = dab.sum_phasor_trig_vcc(1) - v2s0 = blocks.vector_to_stream(gr.sizeof_gr_complex,1) - dst0 = blocks.vector_sink_c() - dst1 = blocks.vector_sink_b() - self.tb.connect(src0, s2v0, (sum_phasor_trig_vcc,0)) - self.tb.connect(src1, (sum_phasor_trig_vcc,1)) - self.tb.connect((sum_phasor_trig_vcc,0), v2s0, dst0) - self.tb.connect((sum_phasor_trig_vcc,1), dst1) - self.tb.run() - result_data0 = dst0.data() - result_data1 = dst1.data() - self.assertComplexTuplesAlmostEqual(expected_result0, result_data0, 6) - self.assertEqual(result_data1, src_data1) + def test_002_sum_phasor_trig_vcc(self): + src_data0 = (1, 1j, -1, 1, + 1) * 50 # try it multiple times to decect problems when leaving the function in between + src_data1 = (1, 0, 0, 1, 0) * 50 + expected_result0 = (1, 1j, -1j, 1, 1) * 50 + expected_result0 = [x + 0j for x in expected_result0] + src0 = blocks.vector_source_c(src_data0) + src1 = blocks.vector_source_b(src_data1) + s2v0 = blocks.stream_to_vector(gr.sizeof_gr_complex, 1) + sum_phasor_trig_vcc = dab.sum_phasor_trig_vcc(1) + v2s0 = blocks.vector_to_stream(gr.sizeof_gr_complex, 1) + dst0 = blocks.vector_sink_c() + dst1 = blocks.vector_sink_b() + self.tb.connect(src0, s2v0, (sum_phasor_trig_vcc, 0)) + self.tb.connect(src1, (sum_phasor_trig_vcc, 1)) + self.tb.connect((sum_phasor_trig_vcc, 0), v2s0, dst0) + self.tb.connect((sum_phasor_trig_vcc, 1), dst1) + self.tb.run() + result_data0 = dst0.data() + result_data1 = dst1.data() + self.assertComplexTuplesAlmostEqual(expected_result0, result_data0, 6) + self.assertEqual(result_data1, src_data1) -if __name__ == '__main__': - gr_unittest.main() +if __name__ == '__main__': + gr_unittest.main() diff --git a/python/qa_time_deinterleave_ff.py b/python/qa/qa_time_deinterleave_ff.py similarity index 87% rename from python/qa_time_deinterleave_ff.py rename to python/qa/qa_time_deinterleave_ff.py index cc76e00d..bca6b0ef 100755 --- a/python/qa_time_deinterleave_ff.py +++ b/python/qa/qa_time_deinterleave_ff.py @@ -24,6 +24,11 @@ import dab_swig as dab class qa_time_deinterleave_ff (gr_unittest.TestCase): + """ + @brief QA for the time deinterleave block + + This class implements a test bench to verify the corresponding C++ class. + """ def setUp (self): self.tb = gr.top_block () @@ -36,14 +41,11 @@ def test_001_t(self): expected_result = (0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) src = blocks.vector_source_b(vector01, True) b2f = blocks.char_to_float_make() - s2v = blocks.stream_to_vector(gr.sizeof_float, 6) time_deinterleaver = dab.time_deinterleave_ff_make(6, [0, 1]) - v2s = blocks.vector_to_stream(gr.sizeof_float, 6) dst = blocks.vector_sink_f() self.tb.connect(src, b2f, time_deinterleaver, blocks.head_make(gr.sizeof_float, 6*3), dst) self.tb.run() result = dst.data() - #print result self.assertEqual(expected_result, result) def test_002_t(self): @@ -51,14 +53,11 @@ def test_002_t(self): expected_result = (0, 0, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 1, 12, 3, 0) src = blocks.vector_source_b(vector01, True) b2f = blocks.char_to_float_make() - s2v = blocks.stream_to_vector(gr.sizeof_float, 4) time_deinterleaver = dab.time_deinterleave_ff_make(4, [0, 3, 2, 1]) - v2s = blocks.vector_to_stream(gr.sizeof_float, 4) dst = blocks.vector_sink_f() self.tb.connect(src, b2f, time_deinterleaver, blocks.head_make(gr.sizeof_float, 4*4), dst) self.tb.run() result = dst.data() - #print result self.assertEqual(expected_result, result) def test_003_t(self): @@ -66,14 +65,11 @@ def test_003_t(self): expected_result = (0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 7, 8, 0, 0, 11, 12, 0, 0, 15, 16, 0, 0, 19,20, 0, 0, 23, 24, 0, 0) src = blocks.vector_source_b(vector01, True) b2f = blocks.char_to_float_make() - s2v = blocks.stream_to_vector(gr.sizeof_float, 8) time_deinterleaver = dab.time_deinterleave_ff_make(8, [2, 3, 0, 1]) - v2s = blocks.vector_to_stream(gr.sizeof_float, 8) dst = blocks.vector_sink_f() self.tb.connect(src, b2f, time_deinterleaver, blocks.head_make(gr.sizeof_float, 8*4), dst) self.tb.run() result = dst.data() - #print result self.assertEqual(expected_result, result) def test_004_t(self): @@ -81,14 +77,11 @@ def test_004_t(self): expected_result = (0,0,0,4,0,0,0,8,0,0,0,12,0,0,0,16,0,0,3,4,0,0,7,8,0,0,11,12,0,0,15,16) src = blocks.vector_source_b(vector01, True) b2f = blocks.char_to_float_make() - s2v = blocks.stream_to_vector(gr.sizeof_float, 16) time_deinterleaver = dab.time_deinterleave_ff_make(16, [0, 1, 2, 4]) - v2s = blocks.vector_to_stream(gr.sizeof_float, 16) dst = blocks.vector_sink_f() self.tb.connect(src, b2f, time_deinterleaver, blocks.head_make(gr.sizeof_float, 16*2), dst) self.tb.run() result = dst.data() - #print result self.assertEqual(expected_result, result) if __name__ == '__main__': diff --git a/python/qa/qa_time_interleave_bb.py b/python/qa/qa_time_interleave_bb.py new file mode 100644 index 00000000..ebb94d49 --- /dev/null +++ b/python/qa/qa_time_interleave_bb.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). +# +# 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. +# + +from gnuradio import gr, gr_unittest +from gnuradio import blocks +import dab_swig as dab + +class qa_time_interleave_bb (gr_unittest.TestCase): + """ + @brief QA for the time interleave block + + This class implements a test bench to verify the corresponding C++ class. + """ + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001_t(self): + vector01 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) + expected_result = (1, 0, 3, 0, 5, 0, 7, 2, 9, 4, 11, 6, 13, 8, 15, 10, 17, 12) + src = blocks.vector_source_b(vector01, True) + s2v = blocks.stream_to_vector_make(gr.sizeof_char, 6) + time_interleaver = dab.time_interleave_bb_make(6, [0, 1]) + v2s = blocks.vector_to_stream_make(gr.sizeof_char, 6) + dst = blocks.vector_sink_b() + self.tb.connect(src, s2v, time_interleaver, blocks.head_make(gr.sizeof_char*6, 3), v2s, dst) + self.tb.run() + result = dst.data() + self.assertEqual(expected_result, result) + + def test_002_t(self): + vector01 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) + expected_result = (1, 0, 0, 0, 5, 0, 0, 4, 9, 0, 3, 8, 13, 2, 7, 12) + src = blocks.vector_source_b(vector01, True) + s2v = blocks.stream_to_vector(gr.sizeof_char, 4) + time_interleaver = dab.time_interleave_bb_make(4, [0, 3, 2, 1]) + v2s = blocks.vector_to_stream(gr.sizeof_char, 4) + dst = blocks.vector_sink_b() + self.tb.connect(src, s2v, time_interleaver, blocks.head_make(gr.sizeof_char*4, 4), v2s, dst) + self.tb.run() + result = dst.data() + self.assertEqual(expected_result, result) + +if __name__ == '__main__': + gr_unittest.run(qa_time_interleave_bb, "qa_time_interleave_bb.xml") diff --git a/python/qa/qa_unpuncture_vff.py b/python/qa/qa_unpuncture_vff.py index 28fdb063..2cdecd66 100755 --- a/python/qa/qa_unpuncture_vff.py +++ b/python/qa/qa_unpuncture_vff.py @@ -1,50 +1,70 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). +# +# 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. +# from gnuradio import gr, gr_unittest, blocks -import dab +import dab_swig as dab import cmath + class qa_unpuncture_vff(gr_unittest.TestCase): - """ - @brief QA for the unpuncturing block. - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_unpuncture_vff(self): - src_data = (0,1,2,3,4,5,6,7,8,9) - punc_seq = (1,0,0,0,1,0,1,1,1) - exp_res = (0,77,77,77,1,77,2,3,4,5,77,77,77,6,77,7,8,9) - src = blocks.vector_source_f(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_float, 5) - unpuncture_vff = dab.unpuncture_vff(punc_seq, 77) - v2s = blocks.vector_to_stream(gr.sizeof_float, 9) - dst = blocks.vector_sink_f() - self.tb.connect(src, s2v, unpuncture_vff, v2s, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(exp_res, result_data) - - def test_002_unpuncture_vff(self): - src_data = (0,1,2,3,4,5,6,7,8,9) - punc_seq = (1,0,0,0,1,0,1,1,1) - exp_res = (0,0,0,0,1,0,2,3,4,5,0,0,0,6,0,7,8,9) - src = blocks.vector_source_f(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_float, 5) - unpuncture_vff = dab.unpuncture_vff(punc_seq) - v2s = blocks.vector_to_stream(gr.sizeof_float, 9) - dst = blocks.vector_sink_f() - self.tb.connect(src, s2v, unpuncture_vff, v2s, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(exp_res, result_data) + """ + @brief QA for the unpuncturing block. -if __name__ == '__main__': - gr_unittest.main() + This class implements a test bench to verify the corresponding C++ class. + """ + + def setUp(self): + self.tb = gr.top_block() + + def tearDown(self): + self.tb = None + def test_001_unpuncture_vff(self): + src_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) + punc_seq = (1, 0, 0, 0, 1, 0, 1, 1, 1) + exp_res = (0, 77, 77, 77, 1, 77, 2, 3, 4, 5, 77, 77, 77, 6, 77, 7, 8, 9) + src = blocks.vector_source_f(src_data) + s2v = blocks.stream_to_vector(gr.sizeof_float, 5) + unpuncture_vff = dab.unpuncture_vff(punc_seq, 77) + v2s = blocks.vector_to_stream(gr.sizeof_float, 9) + dst = blocks.vector_sink_f() + self.tb.connect(src, s2v, unpuncture_vff, v2s, dst) + self.tb.run() + result_data = dst.data() + self.assertFloatTuplesAlmostEqual(exp_res, result_data) + + def test_002_unpuncture_vff(self): + src_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) + punc_seq = (1, 0, 0, 0, 1, 0, 1, 1, 1) + exp_res = (0, 0, 0, 0, 1, 0, 2, 3, 4, 5, 0, 0, 0, 6, 0, 7, 8, 9) + src = blocks.vector_source_f(src_data) + s2v = blocks.stream_to_vector(gr.sizeof_float, 5) + unpuncture_vff = dab.unpuncture_vff(punc_seq) + v2s = blocks.vector_to_stream(gr.sizeof_float, 9) + dst = blocks.vector_sink_f() + self.tb.connect(src, s2v, unpuncture_vff, v2s, dst) + self.tb.run() + result_data = dst.data() + self.assertFloatTuplesAlmostEqual(exp_res, result_data) + + +if __name__ == '__main__': + gr_unittest.main() diff --git a/python/qa_valve_ff.py b/python/qa/qa_valve_ff.py similarity index 93% rename from python/qa_valve_ff.py rename to python/qa/qa_valve_ff.py index f6da153c..384922c7 100755 --- a/python/qa_valve_ff.py +++ b/python/qa/qa_valve_ff.py @@ -1,18 +1,18 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# -# Copyright 2017 <+YOU OR YOUR COMPANY+>. -# +# +# Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). +# # 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, diff --git a/python/qa_peak_detector_fb.py b/python/qa_peak_detector_fb.py deleted file mode 100755 index 71e77bf8..00000000 --- a/python/qa_peak_detector_fb.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright 2007,2010,2013 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# 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. -# - -from gnuradio import gr, gr_unittest -from gnuradio import blocks -import dab_swig as dab - -class qa_peak_detector_fb (gr_unittest.TestCase): - - def setUp (self): - self.tb = gr.top_block () - - def tearDown (self): - self.tb = None - - def test_01(self): - tb = self.tb - - data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - - expected_result = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - - src = blocks.vector_source_f(data, False) - regen = blocks.peak_detector_fb() - dst = blocks.vector_sink_b() - - tb.connect(src, regen) - tb.connect(regen, dst) - tb.run() - - dst_data = dst.data() - - self.assertEqual(expected_result, dst_data) - - def test_02(self): - tb = self.tb - - data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - - expected_result = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - - src = blocks.vector_source_i(data, False) - regen = blocks.peak_detector_ib() - dst = blocks.vector_sink_b() - - tb.connect(src, regen) - tb.connect(regen, dst) - tb.run() - - dst_data = dst.data() - - self.assertEqual(expected_result, dst_data) - - def test_03(self): - tb = self.tb - - data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - - expected_result = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - - src = blocks.vector_source_s(data, False) - regen = blocks.peak_detector_sb() - dst = blocks.vector_sink_b() - - tb.connect(src, regen) - tb.connect(regen, dst) - tb.run() - - dst_data = dst.data() - - self.assertEqual(expected_result, dst_data) - - -if __name__ == '__main__': - gr_unittest.run(qa_peak_detector_fb, "qa_peak_detector_fb.xml") diff --git a/python/qa_repartition_vectors.py b/python/qa_repartition_vectors.py deleted file mode 100755 index 429a6b0f..00000000 --- a/python/qa_repartition_vectors.py +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). -# -# 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. -# - -from gnuradio import gr, gr_unittest, blocks -import dab_swig as dab - - -class qa_repartition_vectors(gr_unittest.TestCase): - """ - @brief QA for the vector repartitioning block - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_repartition_vectors(self): - ilen = 3 - mult = 2 - div = 3 - olen = 2 - src_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6) - trig = (0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0 ) - expected_data = (3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6) - expected_trig = (1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 ) - src = blocks.vector_source_b(src_data) - trigsrc = blocks.vector_source_b(trig) - s2v = blocks.stream_to_vector(gr.sizeof_char, ilen) - repartition_vectors = dab.repartition_vectors(gr.sizeof_char, ilen, olen, mult, div) - v2s = blocks.vector_to_stream(gr.sizeof_char, olen) - dst = blocks.vector_sink_b() - trigdst = blocks.vector_sink_b() - self.tb.connect(src, s2v, repartition_vectors, v2s, dst) - self.tb.connect(trigsrc, (repartition_vectors, 1), trigdst) - self.tb.run() - result_data = dst.data() - result_trig = trigdst.data() - self.assertEqual(expected_data, result_data) - self.assertEqual(expected_trig, result_trig) - - def test_002_repartition_vectors(self): - ilen = 3 - mult = 2 - div = 3 - olen = 2 - src_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6) - trig = (1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 ) - expected_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6) - expected_trig = (1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, ) - src = blocks.vector_source_b(src_data) - trigsrc = blocks.vector_source_b(trig) - s2v = blocks.stream_to_vector(gr.sizeof_char, ilen) - repartition_vectors = dab.repartition_vectors(gr.sizeof_char, ilen, olen, mult, div) - v2s = blocks.vector_to_stream(gr.sizeof_char, olen) - dst = blocks.vector_sink_b() - trigdst = blocks.vector_sink_b() - self.tb.connect(src, s2v, repartition_vectors, v2s, dst) - self.tb.connect(trigsrc, (repartition_vectors, 1), trigdst) - self.tb.run() - result_data = dst.data() - result_trig = trigdst.data() - self.assertEqual(expected_data, result_data) - self.assertEqual(expected_trig, result_trig) - - def test_003_repartition_vectors(self): - ilen = 3 - mult = 4 - div = 5 - olen = 2 - src_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6) - trig = (1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 ) - expected_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5 ) - expected_trig = (1, 0, 0, 0, 0, 1, 0, 0, 0, 0, ) - src = blocks.vector_source_b(src_data) - trigsrc = blocks.vector_source_b(trig) - s2v = blocks.stream_to_vector(gr.sizeof_char, ilen) - repartition_vectors = dab.repartition_vectors(gr.sizeof_char, ilen, olen, mult, div) - v2s = blocks.vector_to_stream(gr.sizeof_char, olen) - dst = blocks.vector_sink_b() - trigdst = blocks.vector_sink_b() - self.tb.connect(src, s2v, repartition_vectors, v2s, dst) - self.tb.connect(trigsrc, (repartition_vectors, 1), trigdst) - self.tb.run() - result_data = dst.data() - result_trig = trigdst.data() - self.assertEqual(expected_data, result_data) - self.assertEqual(expected_trig, result_trig) - -if __name__ == '__main__': - gr_unittest.main() diff --git a/python/qa_select_subch_vfvf.py b/python/qa_select_subch_vfvf.py deleted file mode 100755 index d591af35..00000000 --- a/python/qa_select_subch_vfvf.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). -# -# 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. -# - -from gnuradio import gr, gr_unittest -from gnuradio import blocks -import dab_swig as dab - -class qa_select_subch_vfvf (gr_unittest.TestCase): - - def setUp (self): - self.tb = gr.top_block () - - def tearDown (self): - self.tb = None - - def test_001_select_vectors(self): - vlen_in = 2 - vlen_out = 6 - total_size = 8 - address = 1 - src_data = ( - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) - expected_data = (2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7) - src = blocks.vector_source_f(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_float, vlen_in) - select_subch = dab.select_subch_vfvf_make(vlen_in, vlen_out, address, total_size) - v2s = blocks.vector_to_stream(gr.sizeof_float, vlen_out) - dst = blocks.vector_sink_f() - self.tb.connect(src, s2v, select_subch, v2s, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual2(result_data, expected_data) - - def test_002_select_vectors(self): - vlen_in = 2 - vlen_out = 10 - total_size = 10 - address = 3 - src_data = ( - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0) - expected_data = (6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) - src = blocks.vector_source_f(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_float, vlen_in) - select_subch = dab.select_subch_vfvf_make(vlen_in, vlen_out, address, total_size) - v2s = blocks.vector_to_stream(gr.sizeof_float, vlen_out) - dst = blocks.vector_sink_f() - self.tb.connect(src, s2v, select_subch, v2s, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual2(result_data, expected_data) - - def test_003_select_vectors(self): - vlen_in = 4 - vlen_out = 4 - total_size = 1 - address = 0 - src_data = ( - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19) - expected_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19) - src = blocks.vector_source_f(src_data) - s2v = blocks.stream_to_vector(gr.sizeof_float, vlen_in) - select_subch = dab.select_subch_vfvf_make(vlen_in, vlen_out, address, total_size) - v2s = blocks.vector_to_stream(gr.sizeof_float, vlen_out) - dst = blocks.vector_sink_f() - self.tb.connect(src, s2v, select_subch, v2s, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual2(result_data, expected_data) - -if __name__ == '__main__': - gr_unittest.run(qa_select_subch_vfvf, "qa_select_subch_vfvf.xml") diff --git a/python/qa_select_vectors.py b/python/qa_select_vectors.py deleted file mode 100755 index 4da6e1a3..00000000 --- a/python/qa_select_vectors.py +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). -# -# 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. -# - -from gnuradio import gr, gr_unittest, blocks -import dab_swig as dab - - -class qa_select_vectors(gr_unittest.TestCase): - """ - @brief QA for the vector select block - - This class implements a test bench to verify the corresponding C++ class. - """ - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001_select_vectors(self): - skip = 2 - len = 3 - vlen = 2 - src_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9) - trig = (0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 ) - expected_data = (6, 7, 8, 9, 10, 11, 6, 7, 8, 9) - expected_trig = (1, 0, 0, 1, 0) - src = blocks.vector_source_b(src_data) - trigsrc = blocks.vector_source_b(trig) - s2v = blocks.stream_to_vector(gr.sizeof_char, 2) - select_vectors = dab.select_vectors(gr.sizeof_char, vlen, len, skip) - v2s = blocks.vector_to_stream(gr.sizeof_char, 2) - dst = blocks.vector_sink_b() - trigdst = blocks.vector_sink_b() - self.tb.connect(src, s2v, select_vectors, v2s, dst) - self.tb.connect(trigsrc, (select_vectors, 1), trigdst) - self.tb.run() - result_data = dst.data() - result_trig = trigdst.data() - # print expected_result - # print result_data - self.assertEqual(expected_data, result_data) - self.assertEqual(expected_trig, result_trig) - - def test_002_select_vectors(self): - skip = 2 - len = 3 - vlen = 2 - src_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9) - trig = (0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 ) - expected_data = (6, 7, 8, 9, 10, 11, 6, 7, 8, 9) - expected_trig = (1, 0, 0, 1, 0) - src = blocks.vector_source_f(src_data) - trigsrc = blocks.vector_source_b(trig) - s2v = blocks.stream_to_vector(gr.sizeof_float, 2) - select_vectors = dab.select_vectors(gr.sizeof_float, vlen, len, skip) - v2s = blocks.vector_to_stream(gr.sizeof_float, 2) - dst = blocks.vector_sink_f() - trigdst = blocks.vector_sink_b() - self.tb.connect(src, s2v, select_vectors, v2s, dst) - self.tb.connect(trigsrc, (select_vectors, 1), trigdst) - self.tb.run() - result_data = dst.data() - result_trig = trigdst.data() - # print expected_result - # print result_data - self.assertFloatTuplesAlmostEqual(expected_data, result_data) - self.assertEqual(expected_trig, result_trig) - - def test_003_select_vectors(self): - skip = 3 - len = 2 - vlen = 3 - src_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - trig = (1, 0, 0, 0, 0, 0, 0, 0, 1 ) - expected_data = (9, 10, 11, 12, 13, 14) - expected_trig = (1, 0 ) - src = blocks.vector_source_f(src_data) - trigsrc = blocks.vector_source_b(trig) - s2v = blocks.stream_to_vector(gr.sizeof_float, vlen) - select_vectors = dab.select_vectors(gr.sizeof_float, vlen, len, skip) - v2s = blocks.vector_to_stream(gr.sizeof_float, vlen) - dst = blocks.vector_sink_f() - trigdst = blocks.vector_sink_b() - self.tb.connect(src, s2v, select_vectors, v2s, dst) - self.tb.connect(trigsrc, (select_vectors, 1), trigdst) - self.tb.run() - result_data = dst.data() - result_trig = trigdst.data() - # print expected_result - # print result_data - self.assertFloatTuplesAlmostEqual(expected_data, result_data) - self.assertEqual(expected_trig, result_trig) - - def test_004_select_vectors(self): - skip = 3 - len = 3 - vlen = 3 - src_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - trig = (1, 1, 0, 0, 0, 0, 1, 0, 1 ) - expected_data = (12, 13, 14, 15, 0, 1) - expected_trig = (1, 0 ) - src = blocks.vector_source_f(src_data) - trigsrc = blocks.vector_source_b(trig) - s2v = blocks.stream_to_vector(gr.sizeof_float, vlen) - select_vectors = dab.select_vectors(gr.sizeof_float, vlen, len, skip) - v2s = blocks.vector_to_stream(gr.sizeof_float, vlen) - dst = blocks.vector_sink_f() - trigdst = blocks.vector_sink_b() - self.tb.connect(src, s2v, select_vectors, v2s, dst) - self.tb.connect(trigsrc, (select_vectors, 1), trigdst) - self.tb.run() - result_data = dst.data() - result_trig = trigdst.data() - # print expected_result - # print result_data - self.assertFloatTuplesAlmostEqual(expected_data, result_data) - self.assertEqual(expected_trig, result_trig) - - def test_005_select_vectors(self): - skip = 3 - len = 2 - vlen = 3 - src_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - trig = (1, 1, 0, 0, 1, 0, 1, 0, 0 ) - expected_data = () - expected_trig = () - src = blocks.vector_source_f(src_data) - trigsrc = blocks.vector_source_b(trig) - s2v = blocks.stream_to_vector(gr.sizeof_float, vlen) - select_vectors = dab.select_vectors(gr.sizeof_float, vlen, len, skip) - v2s = blocks.vector_to_stream(gr.sizeof_float, vlen) - dst = blocks.vector_sink_f() - trigdst = blocks.vector_sink_b() - self.tb.connect(src, s2v, select_vectors, v2s, dst) - self.tb.connect(trigsrc, (select_vectors, 1), trigdst) - self.tb.run() - result_data = dst.data() - result_trig = trigdst.data() - # print expected_result - # print result_data - self.assertFloatTuplesAlmostEqual(expected_data, result_data) - self.assertEqual(expected_trig, result_trig) - -if __name__ == '__main__': - gr_unittest.main() diff --git a/python/qa_time_interleave_bb.py b/python/qa_time_interleave_bb.py deleted file mode 100755 index c0a8aa2f..00000000 --- a/python/qa_time_interleave_bb.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). -# -# 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. -# - -from gnuradio import gr, gr_unittest -from gnuradio import blocks -import dab_swig as dab - -class qa_time_interleave_bb (gr_unittest.TestCase): - - def setUp (self): - self.tb = gr.top_block () - - def tearDown (self): - self.tb = None - - def test_001_t (self): - vector01 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) - expected_result = (1, 0, 3, 0, 5, 0, 7, 2, 9, 4, 11, 6, 13, 8, 15, 10, 17, 12) - src = blocks.vector_source_b(vector01, True) - s2v = blocks.stream_to_vector(gr.sizeof_char, 6) - time_interleaver = dab.time_interleave_bb(6, [0, 1]) - v2s = blocks.vector_to_stream(gr.sizeof_char, 6) - dst = blocks.vector_sink_b() - self.tb.connect(src, s2v, time_interleaver, blocks.head_make(gr.sizeof_char*6, 3), v2s, dst) - self.tb.run() - result = dst.data() - #print result - self.assertEqual(expected_result, result) - - def test_002_t(self): - vector01 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) - expected_result = (1,0,0,0, 5, 0, 0, 4, 9,0,3,8, 13, 2, 7, 12) - src = blocks.vector_source_b(vector01, True) - s2v = blocks.stream_to_vector(gr.sizeof_char, 4) - time_interleaver = dab.time_interleave_bb(4, [0, 3, 2, 1]) - v2s = blocks.vector_to_stream(gr.sizeof_char, 4) - dst = blocks.vector_sink_b() - self.tb.connect(src, s2v, time_interleaver, blocks.head_make(gr.sizeof_char * 4, 4), v2s, dst) - self.tb.run() - result = dst.data() - #print result - self.assertEqual(expected_result, result) - - def test_003_t(self): - vector01 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32) - expected_result = (0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 11, 4, 0, 0, 15, 8, 1, 0, 19, 12, 5, 0, 23, 16, 9, 2, 27, 20, 13, 6, 31, 24) - src = blocks.vector_source_b(vector01, True) - s2v = blocks.stream_to_vector(gr.sizeof_char, 8) - time_interleaver = dab.time_interleave_bb(8, [2, 3, 0, 1]) - v2s = blocks.vector_to_stream(gr.sizeof_char, 8) - dst = blocks.vector_sink_b() - self.tb.connect(src, s2v, time_interleaver, blocks.head_make(gr.sizeof_char * 8, 4), v2s, dst) - self.tb.run() - result = dst.data() - #print result - self.assertEqual(expected_result, result) - - def test_004_t(self): - vector01 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36) - expected_result = (0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 11, 4, 0, 0, 15, 8, 1, 0, 19, 12, 5, 0, 23, 16, 9, 2, 27, 20, 13, 6, 31, 24) - src = blocks.vector_source_b(vector01, True) - s2v = blocks.stream_to_vector(gr.sizeof_char, 8) - time_interleaver = dab.time_interleave_bb(8, [2, 3, 0, 1]) - v2s = blocks.vector_to_stream(gr.sizeof_char, 8) - dst = blocks.vector_sink_b() - self.tb.connect(src, s2v, time_interleaver, blocks.head_make(gr.sizeof_char * 8, 4), v2s, dst) - self.tb.run() - result = dst.data() - #print result - self.assertEqual(expected_result, result) - -if __name__ == '__main__': - gr_unittest.run(qa_time_interleave_bb, "qa_time_interleave_bb.xml") diff --git a/python/qa_unpuncture_ff.py b/python/qa_unpuncture_ff.py deleted file mode 100755 index bcf2bf51..00000000 --- a/python/qa_unpuncture_ff.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright 2017 Moritz Luca Schmid, Communications Engineering Lab (CEL) / Karlsruhe Institute of Technology (KIT). -# -# 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. -# - -from gnuradio import gr, gr_unittest -from gnuradio import blocks -import dab_swig as dab - -class qa_unpuncture_ff (gr_unittest.TestCase): - - def setUp (self): - self.tb = gr.top_block () - - def tearDown (self): - self.tb = None - - def test_001_unpuncture_ff(self): - src_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) - punc_seq = (1, 0, 0, 0, 1, 0, 1, 1, 1) - exp_res = (0, 77, 77, 77, 1, 77, 2, 3, 4, 5, 77, 77, 77, 6, 77, 7, 8, 9) - src = blocks.vector_source_f(src_data) - unpuncture_ff = dab.unpuncture_ff(punc_seq, 77) - dst = blocks.vector_sink_f() - self.tb.connect(src, unpuncture_ff, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(exp_res, result_data) - - def test_002_unpuncture_ff(self): - src_data = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) - punc_seq = (1, 0, 0, 0, 1, 0, 1, 1, 1) - exp_res = (0, 0, 0, 0, 1, 0, 2, 3, 4, 5, 0, 0, 0, 6, 0, 7, 8, 9) - src = blocks.vector_source_f(src_data) - unpuncture_ff = dab.unpuncture_ff(punc_seq, 0) - dst = blocks.vector_sink_f() - self.tb.connect(src, unpuncture_ff, dst) - self.tb.run() - result_data = dst.data() - self.assertFloatTuplesAlmostEqual(exp_res, result_data) - - -if __name__ == '__main__': - gr_unittest.run(qa_unpuncture_ff, "qa_unpuncture_ff.xml") diff --git a/python/test_ofdm.py b/python/test_ofdm.py deleted file mode 100755 index b6e88de5..00000000 --- a/python/test_ofdm.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio 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. -# -# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -# test_ofdm.py - test the ofdm demod block -# -# Andreas Mueller, 2008 -# andrmuel@ee.ethz.ch - -from gnuradio import gr, blocks -from gnuradio.eng_option import eng_option -from optparse import OptionParser -from dab import ofdm -import parameters -import random - -class test_ofdm(gr.top_block): - """ - @brief Test program for the ofdm_demod class. - """ - def __init__(self): - gr.top_block.__init__(self) - - - usage = "%prog: [options] samples_file" - parser = OptionParser(option_class=eng_option, usage=usage) - parser.add_option("-m", "--dab-mode", type="int", default=1, - help="DAB mode [default=%default]") - parser.add_option("-F", "--filter-input", action="store_true", default=False, - help="Enable FFT filter at input") - parser.add_option("-s", "--resample-fixed", type="float", default=1, - help="resample by a fixed factor (fractional interpolation)") - parser.add_option("-S", "--autocorrect-sample-rate", action="store_true", default=False, - help="Estimate sample rate offset and resample (dynamic fractional interpolation)") - parser.add_option('-r', '--sample-rate', type="int", default=2048000, - help="Use non-standard sample rate (default=%default)") - parser.add_option('-e', '--equalize-magnitude', action="store_true", default=False, - help="Enable individual carrier magnitude equalizer") - parser.add_option('-d', '--debug', action="store_true", default=False, - help="Write output to files") - parser.add_option('-v', '--verbose', action="store_true", default=False, - help="Print status messages") - (options, args) = parser.parse_args () - - dp = parameters.dab_parameters(options.dab_mode, verbose=options.verbose, sample_rate=options.sample_rate) - - rp = parameters.receiver_parameters(options.dab_mode, input_fft_filter=options.filter_input, autocorrect_sample_rate=options.autocorrect_sample_rate, sample_rate_correction_factor=options.resample_fixed, equalize_magnitude=options.equalize_magnitude, verbose=options.verbose) - - if len(args)<1: - if options.verbose: print "-> using repeating random vector as source" - self.sigsrc = blocks.vector_source_c([10e6*(random.random() + 1j*random.random()) for i in range(0,100000)],True) - self.ns_simulate = blocks.vector_source_c([0.01]*dp.ns_length+[1]*dp.symbols_per_frame*dp.symbol_length,1) - self.mult = blocks.multiply_cc() # simulate null symbols ... - self.src = blocks.throttle( gr.sizeof_gr_complex,2048000) - self.connect(self.sigsrc, (self.mult, 0)) - self.connect(self.ns_simulate, (self.mult, 1)) - self.connect(self.mult, self.src) - else: - filename = args[0] - if options.verbose: print "-> using samples from file " + filename - self.src = blocks.file_source(gr.sizeof_gr_complex, filename, False) - - self.dab_demod = ofdm.ofdm_demod(dp, rp, debug=options.debug, verbose=options.verbose) - - self.connect(self.src, self.dab_demod) - - # sink output to nowhere - self.nop0 = blocks.nop(gr.sizeof_char*dp.num_carriers/4) - self.nop1 = blocks.nop(gr.sizeof_char) - self.connect((self.dab_demod,0),self.nop0) - self.connect((self.dab_demod,1),self.nop1) - -if __name__=='__main__': - try: - to = test_ofdm() - # to.run() - to.run() - to.dump() - to.dab_demod.stop() - - except KeyboardInterrupt: - pass - diff --git a/python/test_ofdm_sync_dab.py b/python/test_ofdm_sync_dab.py deleted file mode 100755 index 913ee883..00000000 --- a/python/test_ofdm_sync_dab.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio 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. -# -# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -# test_ofdm_sync_dab.py - test the DAB OFDM synchronisation -# -# Andreas Mueller, 2008 -# andrmuel@ee.ethz.ch - -from gnuradio import gr, blocks -from gnuradio.eng_option import eng_option -from optparse import OptionParser -from ofdm_sync_dab import ofdm_sync_dab -import parameters -import random -import os - -class dab_ofdm_sync_test(gr.top_block): - """ - @brief Test application for the synchronisation block. - """ - def __init__(self): - gr.top_block.__init__(self) - - usage = "%prog: [options] samples_file" - parser = OptionParser(option_class=eng_option, usage=usage) - (options, args) = parser.parse_args () - if len(args)<1: - # print "using gaussian noise as source" - # self.sigsrc = gr.noise_source_c(gr.GR_GAUSSIAN,10e6) - print "using repeating random vector as source" - self.sigsrc = blocks.vector_source_c([10e6*(random.random() + 1j*random.random()) for i in range(0,100000)],True) - self.src = blocks.throttle( gr.sizeof_gr_complex,2048000) - self.connect(self.sigsrc, self.src) - else: - filename = args[0] - print "using samples from file " + filename - self.src = blocks.file_source(gr.sizeof_gr_complex, filename, False) - - dp = parameters.dab_parameters(1) - rp = parameters.receiver_parameters(1) - self.sync_dab = ofdm_sync_dab(dp, rp, False) - self.nop0 = blocks.nop(gr.sizeof_gr_complex) - self.nop1 = blocks.nop(gr.sizeof_char) - self.connect(self.src, self.sync_dab, self.nop0) - self.connect((self.sync_dab,1), self.nop1) - -if __name__=='__main__': - try: - dab_ofdm_sync_test().run() - except KeyboardInterrupt: - pass diff --git a/swig/dab_swig.i b/swig/dab_swig.i index 16a9edc4..0b97fb9e 100644 --- a/swig/dab_swig.i +++ b/swig/dab_swig.i @@ -8,26 +8,11 @@ %include "dab_swig_doc.i" %{ -#include "dab/moving_sum_ff.h" -#include "dab/ofdm_ffe_all_in_one.h" -#include "dab/ofdm_sampler.h" -#include "dab/ofdm_coarse_frequency_correct.h" #include "dab/diff_phasor_vcc.h" -#include "dab/ofdm_remove_first_symbol_vcc.h" #include "dab/frequency_interleaver_vcc.h" -#include "dab/qpsk_demapper_vcb.h" #include "dab/complex_to_interleaved_float_vcf.h" -#include "dab/modulo_ff.h" -#include "dab/measure_processing_rate.h" -#include "dab/select_vectors.h" -#include "dab/repartition_vectors.h" #include "dab/unpuncture_vff.h" -#include "dab/prune_vectors.h" #include "dab/fib_sink_vb.h" -#include "dab/estimate_sample_rate_bf.h" -#include "dab/fractional_interpolator_triggered_update_cc.h" -#include "dab/magnitude_equalizer_vcc.h" -#include "dab/qpsk_mapper_vbc.h" #include "dab/ofdm_insert_pilot_vcc.h" #include "dab/sum_phasor_trig_vcc.h" #include "dab/ofdm_move_and_insert_zero.h" @@ -36,14 +21,11 @@ #include "dab/time_deinterleave_ff.h" #include "dab/crc16_bb.h" #include "dab/fib_source_b.h" -#include "dab/select_subch_vfvf.h" -#include "dab/unpuncture_ff.h" #include "dab/prune.h" #include "dab/firecode_check_bb.h" #include "dab/puncture_bb.h" #include "dab/dab_transmission_frame_mux_bb.h" #include "dab/conv_encoder_bb.h" -#include "dab/mapper_bc.h" #include "dab/mp2_decode_bs.h" #include "dab/mp4_decode_bs.h" #include "dab/reed_solomon_decode_bb.h" @@ -51,50 +33,30 @@ #include "dab/mp4_encode_sb.h" #include "dab/mp2_encode_sb.h" #include "dab/valve_ff.h" -#include "dab/peak_detector_fb.h" +#include "dab/ofdm_synchronization_cvf.h" +#include "dab/ofdm_coarse_frequency_correction_vcvc.h" +#include "dab/demux_cc.h" +#include "dab/select_cus_vfvf.h" +#include "dab/qpsk_mapper_vbvc.h" %} -%include "dab/moving_sum_ff.h" -GR_SWIG_BLOCK_MAGIC2(dab, moving_sum_ff); -%include "dab/ofdm_ffe_all_in_one.h" -GR_SWIG_BLOCK_MAGIC2(dab, ofdm_ffe_all_in_one); -%include "dab/ofdm_sampler.h" -GR_SWIG_BLOCK_MAGIC2(dab, ofdm_sampler); -%include "dab/ofdm_coarse_frequency_correct.h" -GR_SWIG_BLOCK_MAGIC2(dab, ofdm_coarse_frequency_correct); %include "dab/diff_phasor_vcc.h" GR_SWIG_BLOCK_MAGIC2(dab, diff_phasor_vcc); -%include "dab/ofdm_remove_first_symbol_vcc.h" -GR_SWIG_BLOCK_MAGIC2(dab, ofdm_remove_first_symbol_vcc); + %include "dab/frequency_interleaver_vcc.h" GR_SWIG_BLOCK_MAGIC2(dab, frequency_interleaver_vcc); -%include "dab/qpsk_demapper_vcb.h" -GR_SWIG_BLOCK_MAGIC2(dab, qpsk_demapper_vcb); + %include "dab/complex_to_interleaved_float_vcf.h" GR_SWIG_BLOCK_MAGIC2(dab, complex_to_interleaved_float_vcf); -%include "dab/modulo_ff.h" -GR_SWIG_BLOCK_MAGIC2(dab, modulo_ff); -%include "dab/measure_processing_rate.h" -GR_SWIG_BLOCK_MAGIC2(dab, measure_processing_rate); -%include "dab/select_vectors.h" -GR_SWIG_BLOCK_MAGIC2(dab, select_vectors); -%include "dab/repartition_vectors.h" -GR_SWIG_BLOCK_MAGIC2(dab, repartition_vectors); + + %include "dab/unpuncture_vff.h" GR_SWIG_BLOCK_MAGIC2(dab, unpuncture_vff); -%include "dab/prune_vectors.h" -GR_SWIG_BLOCK_MAGIC2(dab, prune_vectors); + %include "dab/fib_sink_vb.h" GR_SWIG_BLOCK_MAGIC2(dab, fib_sink_vb); -%include "dab/estimate_sample_rate_bf.h" -GR_SWIG_BLOCK_MAGIC2(dab, estimate_sample_rate_bf); -%include "dab/fractional_interpolator_triggered_update_cc.h" -GR_SWIG_BLOCK_MAGIC2(dab, fractional_interpolator_triggered_update_cc); -%include "dab/magnitude_equalizer_vcc.h" -GR_SWIG_BLOCK_MAGIC2(dab, magnitude_equalizer_vcc); -%include "dab/qpsk_mapper_vbc.h" -GR_SWIG_BLOCK_MAGIC2(dab, qpsk_mapper_vbc); + %include "dab/ofdm_insert_pilot_vcc.h" GR_SWIG_BLOCK_MAGIC2(dab, ofdm_insert_pilot_vcc); %include "dab/sum_phasor_trig_vcc.h" @@ -111,10 +73,7 @@ GR_SWIG_BLOCK_MAGIC2(dab, time_deinterleave_ff); GR_SWIG_BLOCK_MAGIC2(dab, crc16_bb); %include "dab/fib_source_b.h" GR_SWIG_BLOCK_MAGIC2(dab, fib_source_b); -%include "dab/select_subch_vfvf.h" -GR_SWIG_BLOCK_MAGIC2(dab, select_subch_vfvf); -%include "dab/unpuncture_ff.h" -GR_SWIG_BLOCK_MAGIC2(dab, unpuncture_ff); + %include "dab/prune.h" GR_SWIG_BLOCK_MAGIC2(dab, prune); %include "dab/firecode_check_bb.h" @@ -125,8 +84,7 @@ GR_SWIG_BLOCK_MAGIC2(dab, puncture_bb); GR_SWIG_BLOCK_MAGIC2(dab, dab_transmission_frame_mux_bb); %include "dab/conv_encoder_bb.h" GR_SWIG_BLOCK_MAGIC2(dab, conv_encoder_bb); -%include "dab/mapper_bc.h" -GR_SWIG_BLOCK_MAGIC2(dab, mapper_bc); + %include "dab/mp2_decode_bs.h" GR_SWIG_BLOCK_MAGIC2(dab, mp2_decode_bs); @@ -144,5 +102,17 @@ GR_SWIG_BLOCK_MAGIC2(dab, mp2_encode_sb); %include "dab/valve_ff.h" GR_SWIG_BLOCK_MAGIC2(dab, valve_ff); -%include "dab/peak_detector_fb.h" -GR_SWIG_BLOCK_MAGIC2(dab, peak_detector_fb); + +%include "dab/ofdm_synchronization_cvf.h" +GR_SWIG_BLOCK_MAGIC2(dab, ofdm_synchronization_cvf); +%include "dab/ofdm_coarse_frequency_correction_vcvc.h" +GR_SWIG_BLOCK_MAGIC2(dab, ofdm_coarse_frequency_correction_vcvc); + + +%include "dab/demux_cc.h" +GR_SWIG_BLOCK_MAGIC2(dab, demux_cc); + +%include "dab/select_cus_vfvf.h" +GR_SWIG_BLOCK_MAGIC2(dab, select_cus_vfvf); +%include "dab/qpsk_mapper_vbvc.h" +GR_SWIG_BLOCK_MAGIC2(dab, qpsk_mapper_vbvc);