diff options
author | Sebastian Koslowski <koslowski@kit.edu> | 2017-01-05 20:51:35 +0100 |
---|---|---|
committer | Sebastian Koslowski <koslowski@kit.edu> | 2017-01-05 20:51:35 +0100 |
commit | 10e7e270773a258b0356bafc3a5bbc4853f38a4c (patch) | |
tree | 5e55f5358a39e8caf453448ddc724ed66b61f387 | |
parent | 7f25c0120fc7bc6a6eeee87878cf387647d51614 (diff) | |
parent | 8d80d0adacc98b02392428ab5284d8417df9c776 (diff) |
Merge remote-tracking branch 'upstream/next' into gtk3
49 files changed, 1717 insertions, 143 deletions
diff --git a/cmake/Modules/GrBoost.cmake b/cmake/Modules/GrBoost.cmake index 1cf8e65a11..39a78c5b86 100644 --- a/cmake/Modules/GrBoost.cmake +++ b/cmake/Modules/GrBoost.cmake @@ -39,9 +39,24 @@ if(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64") list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix endif(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64") -if(MSVC) - set(BOOST_REQUIRED_COMPONENTS ${BOOST_REQUIRED_COMPONENTS} chrono) +if(WIN32) + #The following libraries are either used indirectly, + #or conditionally within the various core components. + #We explicitly list the libraries here because they + #are either required in environments MSVC and MINGW + #or linked-in automatically via header inclusion. + + #However, this is not robust; and its recommended that + #these libraries should be listed in the main components + #list once the minimum version of boost had been bumped + #to a version which always contains these components. + list(APPEND BOOST_REQUIRED_COMPONENTS + atomic + chrono + ) +endif(WIN32) +if(MSVC) if (NOT DEFINED BOOST_ALL_DYN_LINK) set(BOOST_ALL_DYN_LINK TRUE) endif() diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in index 731c0dfed8..fa4cb7ebb8 100644 --- a/docs/doxygen/Doxyfile.in +++ b/docs/doxygen/Doxyfile.in @@ -1624,18 +1624,6 @@ GENERATE_XML = @enable_xml_docs@ XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that diff --git a/docs/doxygen/Doxyfile.swig_doc.in b/docs/doxygen/Doxyfile.swig_doc.in index 37a4d2a710..63bd51de42 100644 --- a/docs/doxygen/Doxyfile.swig_doc.in +++ b/docs/doxygen/Doxyfile.swig_doc.in @@ -1471,18 +1471,6 @@ GENERATE_XML = YES XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that diff --git a/gnuradio-runtime/include/gnuradio/logger.h b/gnuradio-runtime/include/gnuradio/logger.h index 4299a11beb..74b9ee2ea5 100644 --- a/gnuradio-runtime/include/gnuradio/logger.h +++ b/gnuradio-runtime/include/gnuradio/logger.h @@ -30,7 +30,7 @@ */ #ifdef _MSC_VER -typedef unsigned short mode_t; +typedef int mode_t; #else #include <sys/types.h> #endif @@ -103,20 +103,6 @@ namespace gr { #define GR_LOG_GET_LEVEL(logger, level) \ gr::logger_get_level(logger,level); -#define GR_ADD_APPENDER(name, appender) { \ - gr::logger_ptr logger = gr::logger_get_logger(name); \ - gr::logger_add_appender(logger,appender);} - -#define GR_LOG_ADD_APPENDER(logger, appender) { \ - gr::logger_add_appender(logger, appender);} - -#define GR_SET_APPENDER(name, appender) { \ - gr::logger_ptr logger = gr::logger_get_logger(name); \ - gr::logger_set_appender(logger,appender);} - -#define GR_LOG_SET_APPENDER(logger, appender) { \ - gr::logger_set_appender(logger, appender);} - #define GR_ADD_CONSOLE_APPENDER(name, target, pattern) { \ gr::logger_ptr logger = gr::logger_get_logger(name); \ gr::logger_add_console_appender(logger,target,pattern);} @@ -630,18 +616,6 @@ namespace gr { /*! \brief inline function, wrapper for LOG4CPP_ASSERT for conditional ERROR message */ void log_assert(bool cond,std::string msg){GR_LOG_ASSERT(d_logger,cond,msg);} - /*! \brief inline function, Method to add appender to logger by - name (define appender in conf file) */ - void add_appender(std::string appender) { - GR_LOG_ADD_APPENDER(d_logger, appender); - } - - /*! \brief inline function, Method to set an appender to logger by - name (define appender in conf file) */ - void set_appender(std::string appender) { - GR_LOG_SET_APPENDER(d_logger, appender); - } - /*! \brief inline function, Method to add console appender to logger */ void add_console_appender(std::string target,std::string pattern) { GR_LOG_ADD_CONSOLE_APPENDER(d_logger, target, pattern); diff --git a/gnuradio-runtime/include/gnuradio/tags.h b/gnuradio-runtime/include/gnuradio/tags.h index 0551e468d1..df65e50698 100644 --- a/gnuradio-runtime/include/gnuradio/tags.h +++ b/gnuradio-runtime/include/gnuradio/tags.h @@ -69,6 +69,24 @@ namespace gr { { } + tag_t(const tag_t &rhs) + : offset(rhs.offset), + key(rhs.key), + value(rhs.value), + srcid(rhs.srcid) + { + } + tag_t& operator=(const tag_t &rhs) + { + if (this != &rhs) { + offset = rhs.offset; + key = rhs.key; + value = rhs.value; + srcid = rhs.srcid; + } + return (*this); + } + ~tag_t() { } diff --git a/gnuradio-runtime/lib/pmt/pmt.cc b/gnuradio-runtime/lib/pmt/pmt.cc index e09452e60e..da2a7e5cc2 100644 --- a/gnuradio-runtime/lib/pmt/pmt.cc +++ b/gnuradio-runtime/lib/pmt/pmt.cc @@ -63,9 +63,18 @@ pmt_base::operator delete(void *p, size_t size) #endif -void intrusive_ptr_add_ref(pmt_base* p) { ++(p->count_); } -void intrusive_ptr_release(pmt_base* p) { if (--(p->count_) == 0 ) delete p; } +void intrusive_ptr_add_ref(pmt_base* p) +{ + p->refcount_.fetch_add(1, boost::memory_order_relaxed); +} +void intrusive_ptr_release(pmt_base* p) { + if (p->refcount_.fetch_sub(1, boost::memory_order_release) == 1) { + boost::atomic_thread_fence(boost::memory_order_acquire); + delete p; + } +} + pmt_base::~pmt_base() { // nop -- out of line virtual destructor diff --git a/gnuradio-runtime/lib/pmt/pmt_int.h b/gnuradio-runtime/lib/pmt/pmt_int.h index 49bde52063..f06f507944 100644 --- a/gnuradio-runtime/lib/pmt/pmt_int.h +++ b/gnuradio-runtime/lib/pmt/pmt_int.h @@ -24,7 +24,8 @@ #include <pmt/pmt.h> #include <boost/utility.hpp> -#include <boost/detail/atomic_count.hpp> +#include <boost/version.hpp> +#include <boost/atomic.hpp> /* * EVERYTHING IN THIS FILE IS PRIVATE TO THE IMPLEMENTATION! @@ -36,10 +37,10 @@ namespace pmt { class PMT_API pmt_base : boost::noncopyable { - mutable boost::detail::atomic_count count_; + mutable boost::atomic<int> refcount_; protected: - pmt_base() : count_(0) {}; + pmt_base() : refcount_(0) {}; virtual ~pmt_base(); public: diff --git a/gr-audio/lib/windows/windows_sink.cc b/gr-audio/lib/windows/windows_sink.cc index 52456dbdc4..bd9e0e5660 100644 --- a/gr-audio/lib/windows/windows_sink.cc +++ b/gr-audio/lib/windows/windows_sink.cc @@ -93,7 +93,7 @@ namespace gr { std::runtime_error("audio_windows_sink:open_waveout_device() failed"); } else if (verbose) { - GR_LOG_INFO(logger, "Opened windows waveout device"); + GR_LOG_INFO(d_logger, "Opened windows waveout device"); } d_buffers = new LPWAVEHDR[nPeriods]; for (int i = 0; i < nPeriods; i++) @@ -104,7 +104,7 @@ namespace gr { d_buffers[i]->dwBufferLength = d_buffer_size; d_buffers[i]->lpData = new CHAR[d_buffer_size]; } - if (verbose) GR_LOG_INFO(logger, boost::format("Initialized %1% %2%ms audio buffers, total memory used: %3$0.2fkB") % (nPeriods) % (CHUNK_TIME * 1000) % ((d_buffer_size * nPeriods) / 1024.0)); + if (verbose) GR_LOG_INFO(d_logger, boost::format("Initialized %1% %2%ms audio buffers, total memory used: %3$0.2fkB") % (nPeriods) % (CHUNK_TIME * 1000) % ((d_buffer_size * nPeriods) / 1024.0)); } windows_sink::~windows_sink() @@ -252,7 +252,7 @@ namespace gr { result = num; } else { - GR_LOG_INFO(logger, boost::format("Warning: waveOut deviceID %d was not found, defaulting to WAVE_MAPPER") % num); + GR_LOG_INFO(d_logger, boost::format("Warning: waveOut deviceID %d was not found, defaulting to WAVE_MAPPER") % num); result = WAVE_MAPPER; } @@ -271,10 +271,10 @@ namespace gr { { result = i; } - if (verbose) GR_LOG_INFO(logger, boost::format("WaveOut Device %d: %s") % i % woc.szPname); + if (verbose) GR_LOG_INFO(d_logger, boost::format("WaveOut Device %d: %s") % i % woc.szPname); } if (result == -1) { - GR_LOG_INFO(logger, boost::format("Warning: waveOut device '%s' was not found, defaulting to WAVE_MAPPER") % szDeviceName); + GR_LOG_INFO(d_logger, boost::format("Warning: waveOut device '%s' was not found, defaulting to WAVE_MAPPER") % szDeviceName); result = WAVE_MAPPER; } } @@ -306,14 +306,14 @@ namespace gr { // would know the device ID so at the moment we will ignore that setting // and stick with WAVE_MAPPER u_device_id = find_device(d_device_name); - if (verbose) GR_LOG_INFO(logger, boost::format("waveOut Device ID: %1%") % (u_device_id)); + if (verbose) GR_LOG_INFO(d_logger, boost::format("waveOut Device ID: %1%") % (u_device_id)); // Check if the sampling rate/bits/channels are good to go with the device. MMRESULT supported = is_format_supported(&wave_format, u_device_id); if (supported != MMSYSERR_NOERROR) { char err_msg[50]; waveOutGetErrorText(supported, err_msg, 50); - GR_LOG_INFO(logger, boost::format("format error: %s") % err_msg); + GR_LOG_INFO(d_logger, boost::format("format error: %s") % err_msg); perror("audio_windows_sink: Requested audio format is not supported by device driver"); return -1; } diff --git a/gr-audio/lib/windows/windows_source.cc b/gr-audio/lib/windows/windows_source.cc index f458fa474e..372a8ba3a8 100644 --- a/gr-audio/lib/windows/windows_source.cc +++ b/gr-audio/lib/windows/windows_source.cc @@ -97,7 +97,7 @@ namespace gr { std::runtime_error("audio_windows_source:open_wavein_device() failed"); } else if (verbose) { - GR_LOG_INFO(logger, "Opened windows wavein device"); + GR_LOG_INFO(d_logger, "Opened windows wavein device"); } lp_buffers = new LPWAVEHDR[nPeriods]; for (int i = 0; i < nPeriods; i++) @@ -118,7 +118,7 @@ namespace gr { waveInAddBuffer(d_h_wavein, lp_buffer, sizeof(WAVEHDR)); } waveInStart(d_h_wavein); - if (verbose) GR_LOG_INFO(logger, boost::format("Initialized %1% %2%ms audio buffers, total memory used: %3$0.2fkB") % (nPeriods) % (CHUNK_TIME * 1000) % ((d_buffer_size * nPeriods) / 1024.0)); + if (verbose) GR_LOG_INFO(d_logger, boost::format("Initialized %1% %2%ms audio buffers, total memory used: %3$0.2fkB") % (nPeriods) % (CHUNK_TIME * 1000) % ((d_buffer_size * nPeriods) / 1024.0)); } windows_source::~windows_source() @@ -237,7 +237,7 @@ namespace gr { result = num; } else { - GR_LOG_INFO(logger, boost::format("Warning: waveIn deviceID %d was not found, defaulting to WAVE_MAPPER") % num); + GR_LOG_INFO(d_logger, boost::format("Warning: waveIn deviceID %d was not found, defaulting to WAVE_MAPPER") % num); result = WAVE_MAPPER; } @@ -256,10 +256,10 @@ namespace gr { { result = i; } - if (verbose) GR_LOG_INFO(logger, boost::format("WaveIn Device %d: %s") % i % woc.szPname); + if (verbose) GR_LOG_INFO(d_logger, boost::format("WaveIn Device %d: %s") % i % woc.szPname); } if (result == -1) { - GR_LOG_INFO(logger, boost::format("Warning: waveIn device '%s' was not found, defaulting to WAVE_MAPPER") % szDeviceName); + GR_LOG_INFO(d_logger, boost::format("Warning: waveIn device '%s' was not found, defaulting to WAVE_MAPPER") % szDeviceName); result = WAVE_MAPPER; } } @@ -291,14 +291,14 @@ namespace gr { // would know the device ID so at the moment we will ignore that setting // and stick with WAVE_MAPPER u_device_id = find_device(d_device_name); - if (verbose) GR_LOG_INFO(logger, boost::format("waveIn Device ID: %1%") % (u_device_id)); + if (verbose) GR_LOG_INFO(d_logger, boost::format("waveIn Device ID: %1%") % (u_device_id)); // Check if the sampling rate/bits/channels are good to go with the device. MMRESULT supported = is_format_supported(&wave_format, u_device_id); if (supported != MMSYSERR_NOERROR) { char err_msg[50]; waveInGetErrorText(supported, err_msg, 50); - GR_LOG_INFO(logger, boost::format("format error: %s") % err_msg); + GR_LOG_INFO(d_logger, boost::format("format error: %s") % err_msg); perror("audio_windows_source: Requested audio format is not supported by device driver"); return -1; } diff --git a/gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc b/gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc index d14b46a0e1..123e7fb15e 100644 --- a/gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc +++ b/gr-dtv/lib/dvb/dvb_bbheader_bb_impl.cc @@ -326,7 +326,7 @@ namespace gr { void dvb_bbheader_bb_impl::build_crc8_table(void) { - int r,crc; + int r, crc; for (int i = 0; i < 256; i++) { r = i; diff --git a/gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.cc b/gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.cc index ef1c1841ad..8e86eb4f64 100644 --- a/gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.cc +++ b/gr-dtv/lib/dvb/dvb_bbscrambler_bb_impl.cc @@ -279,8 +279,7 @@ namespace gr { unsigned char *out = (unsigned char *) output_items[0]; for (int i = 0; i < noutput_items; i += kbch) { - for (int j = 0; j < (int)kbch; ++j) - { + for (int j = 0; j < (int)kbch; ++j) { out[i + j] = in[i + j] ^ bb_randomise[j]; } } diff --git a/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc b/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc index b1ebb6db79..8d89f9b04a 100644 --- a/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc +++ b/gr-dtv/lib/dvb/dvb_bch_bb_impl.cc @@ -385,7 +385,7 @@ namespace gr { void dvb_bch_bb_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) { - ninput_items_required[0] = (noutput_items / nbch) * kbch; + ninput_items_required[0] = (noutput_items / nbch) * kbch; } /* diff --git a/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc b/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc index 568aac940a..84328e1200 100644 --- a/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc +++ b/gr-dtv/lib/dvb/dvb_ldpc_bb_impl.cc @@ -369,12 +369,12 @@ namespace gr { void dvb_ldpc_bb_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) { - ninput_items_required[0] = (noutput_items / frame_size) * nbch; + ninput_items_required[0] = (noutput_items / frame_size) * nbch; } #define LDPC_BF(TABLE_NAME, ROWS) \ for (int row = 0; row < ROWS; row++) { \ - for(int n = 0; n < 360; n++) { \ + for (int n = 0; n < 360; n++) { \ for (int col = 1; col <= TABLE_NAME[row][0]; col++) { \ ldpc_encode.p[index] = (TABLE_NAME[row][col] + (n * q)) % pbits; \ ldpc_encode.d[index] = im; \ @@ -606,7 +606,7 @@ for (int row = 0; row < ROWS; row++) { \ unsigned char *out = (unsigned char *) output_items[0]; const unsigned char *d; unsigned char *p; - unsigned char *b; + unsigned char *b = (unsigned char *) output_items[0]; unsigned char *s; // Calculate the number of parity bits int plen = (frame_size_real + Xp) - nbch; @@ -657,7 +657,7 @@ for (int row = 0; row < ROWS; row++) { \ p[j] ^= p[j-1]; } if (signal_constellation == MOD_128APSK) { - for(int j = 0; j < 6; j++) { + for (int j = 0; j < 6; j++) { p[j + plen] = 0; } } diff --git a/gr-dtv/lib/dvbs2/dvbs2_modulator_bc_impl.cc b/gr-dtv/lib/dvbs2/dvbs2_modulator_bc_impl.cc index 3ae1debb01..e3fb039c50 100644 --- a/gr-dtv/lib/dvbs2/dvbs2_modulator_bc_impl.cc +++ b/gr-dtv/lib/dvbs2/dvbs2_modulator_bc_impl.cc @@ -53,6 +53,7 @@ namespace gr { m_bpsk[0][1] = gr_complex((r1 * cos(5.0 * M_PI / 4.0)), (r1 * sin(5.0 * M_PI / 4.0))); m_bpsk[1][0] = gr_complex((r1 * cos(5.0 * M_PI / 4.0)), (r1 * sin(M_PI / 4.0))); m_bpsk[1][1] = gr_complex((r1 * cos(M_PI / 4.0)), (r1 * sin(5.0 * M_PI /4.0))); + break; case MOD_QPSK: m_qpsk[0] = gr_complex((r1 * cos(M_PI / 4.0)), (r1 * sin(M_PI / 4.0))); m_qpsk[1] = gr_complex((r1 * cos(7 * M_PI / 4.0)), (r1 * sin(7 * M_PI / 4.0))); diff --git a/gr-dtv/lib/dvbs2/dvbs2_physical_cc_impl.cc b/gr-dtv/lib/dvbs2/dvbs2_physical_cc_impl.cc index 688ad7a40c..5da18b1d21 100644 --- a/gr-dtv/lib/dvbs2/dvbs2_physical_cc_impl.cc +++ b/gr-dtv/lib/dvbs2/dvbs2_physical_cc_impl.cc @@ -71,6 +71,7 @@ namespace gr { } else { frame_size = FRAME_SIZE_MEDIUM - MEDIUM_PUNCTURING + EXTRA_PILOT_SYMBOLS_SET1; + type = 0; pilots = PILOTS_ON; /* force pilots on for VL-SNR */ } diff --git a/gr-dtv/lib/dvbt2/dvbt2_freqinterleaver_cc_impl.cc b/gr-dtv/lib/dvbt2/dvbt2_freqinterleaver_cc_impl.cc index f89d2af7f7..bda49e9540 100644 --- a/gr-dtv/lib/dvbt2/dvbt2_freqinterleaver_cc_impl.cc +++ b/gr-dtv/lib/dvbt2/dvbt2_freqinterleaver_cc_impl.cc @@ -186,6 +186,8 @@ namespace gr { max_states = 0; logic = &logic1k[0]; xor_size = 0; + bitpermeven = &bitperm1keven[0]; + bitpermodd = &bitperm1kodd[0]; break; } switch (fftsize) { diff --git a/gr-dtv/lib/dvbt2/dvbt2_modulator_bc_impl.cc b/gr-dtv/lib/dvbt2/dvbt2_modulator_bc_impl.cc index 28e7c4fac2..b92738603b 100644 --- a/gr-dtv/lib/dvbt2/dvbt2_modulator_bc_impl.cc +++ b/gr-dtv/lib/dvbt2/dvbt2_modulator_bc_impl.cc @@ -500,7 +500,7 @@ namespace gr { void dvbt2_modulator_bc_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) { - ninput_items_required[0] = noutput_items; + ninput_items_required[0] = noutput_items; } int diff --git a/gr-uhd/apps/uhd_app.py b/gr-uhd/apps/uhd_app.py index 8e377f0b4d..f9b08a6457 100644 --- a/gr-uhd/apps/uhd_app.py +++ b/gr-uhd/apps/uhd_app.py @@ -135,6 +135,15 @@ class UHDApp(object): )) return specs + def normalize_lo_source_export_sel(self, args): + lo_source = [x.strip() for x in args.lo_source.split(",")] + lo_export = [x.strip() for x in args.lo_export.split(",")] + if len(lo_source) != len(self.channels): + raise ValueError("Invalid number of lo-source settings {n} for {c} channels. Must be one argument per channel.".format(n=len(lo_source), c=len(args.channels))) + if len(lo_export) != len(self.channels): + raise ValueError("Invalid number of lo-export settings {n} for {c} channels. Must be one argument per channel.".format(n=len(lo_source), c=len(args.channels))) + return (lo_source, lo_export) + def async_callback(self, msg): """ Call this when USRP async metadata needs printing. @@ -187,23 +196,49 @@ class UHDApp(object): self.antenna = self.normalize_antenna_sel(args) if self.antenna is not None: for i, chan in enumerate(self.channels): - if not self.antenna[i] in self.usrp.get_antennas(chan): + if not self.antenna[i] in self.usrp.get_antennas(i): self.vprint("[ERROR] {} is not a valid antenna name for this USRP device!".format(self.antenna[i])) exit(1) - self.usrp.set_antenna(self.antenna[i], chan) + self.usrp.set_antenna(self.antenna[i], i) self.vprint("[{prefix}] Channel {chan}: Using antenna {ant}.".format( - prefix=self.prefix, chan=chan, ant=self.usrp.get_antenna(chan) + prefix=self.prefix, chan=chan, ant=self.usrp.get_antenna(i) )) - self.antenna = self.usrp.get_antenna(self.channels[0]) + self.antenna = self.usrp.get_antenna(0) # Set receive daughterboard gain: self.set_gain(args.gain) - self.gain_range = self.usrp.get_gain_range(self.channels[0]) + self.gain_range = self.usrp.get_gain_range(0) # Set frequency (tune request takes lo_offset): if hasattr(args, 'lo_offset') and args.lo_offset is not None: treq = uhd.tune_request(args.freq, args.lo_offset) else: treq = uhd.tune_request(args.freq) self.has_lo_sensor = 'lo_locked' in self.usrp.get_sensor_names() + # Set LO export and LO source operation + if (args.lo_export is not None) and (args.lo_source is not None): + (args.lo_source,args.lo_export) = self.normalize_lo_source_export_sel(args) + for chan,lo_source,lo_export in zip(self.channels,args.lo_source,args.lo_export): + if (lo_source == "None") or (lo_export == "None"): + continue + if lo_export == "True": + #If channel is LO source set frequency and store response + self.usrp.set_lo_export_enabled(True, uhd.ALL_LOS, chan) + if lo_source == "internal": + self.lo_source_channel = chan + tune_resp = self.usrp.set_center_freq(treq,chan) + self.usrp.set_lo_source(lo_source, uhd.ALL_LOS,chan) + # Use lo source tune response to tune dsp_freq on remaining channels + if getattr(args, 'lo_offset', None) is not None: + treq = uhd.tune_request(target_freq=args.freq, rf_freq=args.freq+args.lo_offset, rf_freq_policy=uhd.tune_request.POLICY_MANUAL, + dsp_freq=tune_resp.actual_dsp_freq, + dsp_freq_policy=uhd.tune_request.POLICY_MANUAL) + else: + treq = uhd.tune_request(target_freq=args.freq, rf_freq=args.freg, rf_freq_policy=uhd.tune_request.POLICY_MANUAL, + dsp_freq=tune_resp.actual_dsp_freq, + dsp_freq_policy=uhd.tune_request.POLICY_MANUAL) + for chan in args.channels: + if chan == self.lo_source_channel: + continue + self.usrp.set_center_freq(treq,chan) # Make sure tuning is synched: command_time_set = False if len(self.channels) > 1: @@ -216,8 +251,8 @@ class UHDApp(object): command_time_set = True except RuntimeError: sys.stderr.write('[{prefix}] [WARNING] Failed to set command times.\n'.format(prefix=self.prefix)) - for chan in self.channels: - self.tr = self.usrp.set_center_freq(treq, chan) + for i, chan in enumerate(self.channels): + self.tr = self.usrp.set_center_freq(treq, i) if self.tr == None: sys.stderr.write('[{prefix}] [ERROR] Failed to set center frequency on channel {chan}\n'.format( prefix=self.prefix, chan=chan @@ -228,7 +263,7 @@ class UHDApp(object): self.usrp.clear_command_time(mb_idx) self.vprint("Syncing channels...".format(prefix=self.prefix)) time.sleep(COMMAND_DELAY) - self.freq = self.usrp.get_center_freq(self.channels[0]) + self.freq = self.usrp.get_center_freq(0) if args.show_async_msg: self.async_msgq = gr.msg_queue(0) self.async_src = uhd.amsg_source("", self.async_msgq) @@ -243,17 +278,17 @@ class UHDApp(object): if gain is None: if self.args.verbose: self.vprint("Defaulting to mid-point gains:".format(prefix=self.prefix)) - for chan in self.channels: - self.usrp.set_normalized_gain(.5, chan) + for i, chan in enumerate(self.channels): + self.usrp.set_normalized_gain(.5, i) if self.args.verbose: self.vprint("Channel {chan} gain: {g} dB".format( - prefix=self.prefix, chan=chan, g=self.usrp.get_gain(chan) + prefix=self.prefix, chan=chan, g=self.usrp.get_gain(i) )) else: self.vprint("Setting gain to {g} dB.".format(g=gain)) - for chan in self.channels: + for chan in range( len( self.channels ) ): self.usrp.set_gain(gain, chan) - self.gain = self.usrp.get_gain(self.channels[0]) + self.gain = self.usrp.get_gain(0) def set_freq(self, freq, skip_sync=False): """ @@ -265,6 +300,22 @@ class UHDApp(object): treq = uhd.tune_request(freq, self.args.lo_offset) else: treq = uhd.tune_request(freq) + # Special TwinRX tuning due to LO sharing + if getattr(self, 'lo_source_channel', None) is not None: + tune_resp = self.usrp.set_center_freq(treq, self.lo_source_channel) + if getattr(self.args, 'lo_offset', None) is not None: + treq = uhd.tune_request(target_freq=freq, rf_freq=freq+self.args.lo_offset, rf_freq_policy=uhd.tune_request.POLICY_MANUAL, + dsp_freq=tune_resp.actual_dsp_freq, + dsp_freq_policy=uhd.tune_request.POLICY_MANUAL) + else: + treq = uhd.tune_request(target_freq=freq, rf_freq=freq, rf_freq_policy=uhd.tune_reqest.POLICY_MANUAL, + dsp_freq=tune_resp.actual_dsp_freq, + dsp_freq_policy=uhd.tune_request.POLICY_MANUAL) + for chan in self.channels: + if chan == self.lo_source_channel: + continue + self.usrp.set_center_freq(treq,chan) + # Make sure tuning is synched: command_time_set = False if len(self.channels) > 1 and not skip_sync: @@ -275,8 +326,8 @@ class UHDApp(object): command_time_set = True except RuntimeError: sys.stderr.write('[{prefix}] [WARNING] Failed to set command times.\n'.format(prefix=self.prefix)) - for chan in self.channels: - self.tr = self.usrp.set_center_freq(treq, chan) + for i, chan in enumerate(self.channels ): + self.tr = self.usrp.set_center_freq(treq, i) if self.tr == None: sys.stderr.write('[{prefix}] [ERROR] Failed to set center frequency on channel {chan}\n'.format( prefix=self.prefix, chan=chan @@ -287,7 +338,7 @@ class UHDApp(object): self.usrp.clear_command_time(mb_idx) self.vprint("Syncing channels...".format(prefix=self.prefix)) time.sleep(COMMAND_DELAY) - self.freq = self.usrp.get_center_freq(self.channels[0]) + self.freq = self.usrp.get_center_freq(0) self.vprint("First channel has freq: {freq} MHz.".format(freq=self.freq/1e6)) @staticmethod @@ -333,6 +384,8 @@ class UHDApp(object): if allow_mimo: group.add_argument("-c", "--channels", default=[0,], type=cslist, help="Select {xx} Channels".format(xx=tx_or_rx)) + group.add_argument("--lo-export", help="Set TwinRX LO export {None, True, False} for each channel with a comma-separated list. None skips a channel.") + group.add_argument("--lo-source", help="Set TwinRX LO source {None, internal, companion, external} for each channel with a comma-separated list. None skips this channel. ") group.add_argument("--otw-format", choices=['sc16', 'sc12', 'sc8'], default='sc16', help="Choose over-the-wire data format") group.add_argument("--stream-args", default="", help="Set additional stream arguments") diff --git a/gr-uhd/apps/uhd_fft b/gr-uhd/apps/uhd_fft index aa10cdf900..b65bb7a062 100755 --- a/gr-uhd/apps/uhd_fft +++ b/gr-uhd/apps/uhd_fft @@ -126,8 +126,8 @@ class uhd_fft(gr.top_block, Qt.QWidget, UHDApp): # Blocks ################################################## self.setup_usrp(uhd.usrp_source, args) - self._ant_options = self.usrp.get_antennas(self.channels[0]) - for c in self.channels: + self._ant_options = self.usrp.get_antennas(0) + for c in range(len(self.channels)): self.usrp.set_bandwidth(self.samp_rate, c) self.usrp_device_info = self.get_usrp_info_string(compact=True, tx_or_rx='rx') @@ -320,7 +320,7 @@ class uhd_fft(gr.top_block, Qt.QWidget, UHDApp): self.top_grid_layout.addWidget(self._lo_locked_probe_tool_bar, 4,0,1,2) def _current_freq_probe(): while True: - val = self.usrp.get_center_freq(self.channels[0]) + val = self.usrp.get_center_freq(0) try: if val != self.freq: self.set_freq_qt(val, tune_source='freqsink_msg') @@ -347,15 +347,15 @@ class uhd_fft(gr.top_block, Qt.QWidget, UHDApp): ################################################## self.msg_connect((self.qtgui_freq_sink_x_0, 'freq'), (self.qtgui_freq_sink_x_0, 'freq')) self.msg_connect((self.qtgui_freq_sink_x_0, 'freq'), (self.usrp, 'command')) - for c, idx in enumerate(self.channels): - self.connect((self.usrp, c), (self.qtgui_freq_sink_x_0, idx)) - self.connect((self.usrp, c), (self.qtgui_time_sink_x_0, idx)) - self.connect((self.usrp, c), (self.qtgui_waterfall_sink_x_0, idx)) + for idx in range(len(self.channels)): + self.connect((self.usrp, idx), (self.qtgui_freq_sink_x_0, idx)) + self.connect((self.usrp, idx), (self.qtgui_time_sink_x_0, idx)) + self.connect((self.usrp, idx), (self.qtgui_waterfall_sink_x_0, idx)) if args.phase_relations and len(self.channels) > 1: - for c, idx in enumerate(self.channels[:-1]): + for idx in range(len(self.channels[:-1])): self.connect_phase_plot( - (self.usrp, c), - (self.usrp, self.channels[idx+1]), + (self.usrp, idx), + (self.usrp, idx+1), (self.qtgui_phase_plot, idx) ) @@ -430,7 +430,7 @@ class uhd_fft(gr.top_block, Qt.QWidget, UHDApp): self.qtgui_time_sink_x_0.set_samp_rate(self.samp_rate) self.qtgui_waterfall_sink_x_0.set_frequency_range(self.freq, self.samp_rate) self.usrp.set_samp_rate(self.samp_rate) - for c in self.channels: + for c in range(len(self.channels)): self.usrp.set_bandwidth(self.samp_rate, c) def set_lo_locked_probe(self, lo_locked_probe): @@ -440,7 +440,7 @@ class uhd_fft(gr.top_block, Qt.QWidget, UHDApp): def set_ant(self, ant): self.antenna = ant self._ant_callback(self.antenna) - for c in self.channels: + for c in range(len(self.channels)): self.usrp.set_antenna(self.antenna, c) diff --git a/gr-uhd/doc/uhd.dox b/gr-uhd/doc/uhd.dox index 27a1475566..a3de8e3a24 100644 --- a/gr-uhd/doc/uhd.dox +++ b/gr-uhd/doc/uhd.dox @@ -57,8 +57,8 @@ which automatically sets the PMT types. Assume we only want to set the frequency (i.e. the second channel). In this case, we must construct a dictionary: \code{.cpp} pmt::pmt_t command = pmt::make_dict(); -pmt::dict_add(command, pmt::mp("freq"), pmt::mp(1.1e9)); // Specify frequency -pmt::dict_add(command, pmt::mp("chan"), pmt::mp(1)); // Specify channel +command = pmt::dict_add(command, pmt::mp("freq"), pmt::mp(1.1e9)); // Specify frequency +command = pmt::dict_add(command, pmt::mp("chan"), pmt::mp(1)); // Specify channel // Now pass 'command' into the USRP block's command port \endcode @@ -72,8 +72,8 @@ The main difference is that we can add more properties to the same command PMT, e.g. as such: \code{.cpp} // 'command' is the same PMT as in the previous example -pmt::dict_add(command, pmt::mp("gain"), pmt::mp(23.0)); // Specify gain -pmt::dict_add(command, pmt::mp("antenna"), pmt::mp("TX/RX")); // Switch antenna +command = pmt::dict_add(command, pmt::mp("gain"), pmt::mp(23.0)); // Specify gain +command = pmt::dict_add(command, pmt::mp("antenna"), pmt::mp("TX/RX")); // Switch antenna // Now pass 'command' into the USRP block's command port \endcode When the USRP block interprets this command PMT, all properties will be diff --git a/gr-uhd/lib/usrp_sink_impl.cc b/gr-uhd/lib/usrp_sink_impl.cc index 6288b80cc8..4e2e9467dd 100644 --- a/gr-uhd/lib/usrp_sink_impl.cc +++ b/gr-uhd/lib/usrp_sink_impl.cc @@ -141,12 +141,16 @@ namespace gr { void usrp_sink_impl::set_normalized_gain(double norm_gain, size_t chan) { +#ifdef UHD_USRP_MULTI_USRP_NORMALIZED_GAIN + _dev->set_normalized_tx_gain(norm_gain, chan); +#else if (norm_gain > 1.0 || norm_gain < 0.0) { throw std::runtime_error("Normalized gain out of range, must be in [0, 1]."); } ::uhd::gain_range_t gain_range = get_gain_range(chan); double abs_gain = (norm_gain * (gain_range.stop() - gain_range.start())) + gain_range.start(); set_gain(abs_gain, chan); +#endif } double @@ -166,6 +170,9 @@ namespace gr { double usrp_sink_impl::get_normalized_gain(size_t chan) { +#ifdef UHD_USRP_MULTI_USRP_NORMALIZED_GAIN + return _dev->get_normalized_tx_gain(chan); +#else ::uhd::gain_range_t gain_range = get_gain_range(chan); double norm_gain = (get_gain(chan) - gain_range.start()) / @@ -174,6 +181,7 @@ namespace gr { if (norm_gain > 1.0) return 1.0; if (norm_gain < 0.0) return 0.0; return norm_gain; +#endif } std::vector<std::string> @@ -329,9 +337,11 @@ namespace gr { } //send all ninput_items with metadata + boost::this_thread::disable_interruption disable_interrupt; const size_t num_sent = _tx_stream->send( input_items, ninput_items, _metadata, 1.0 ); + boost::this_thread::restore_interruption restore_interrupt(disable_interrupt); //if using length_tags, decrement items left to send by the number of samples sent if(not pmt::is_null(_length_tag_key) && _nitems_to_send > 0) { diff --git a/gr-uhd/lib/usrp_source_impl.cc b/gr-uhd/lib/usrp_source_impl.cc index c840c43db1..8cdaebc4ca 100644 --- a/gr-uhd/lib/usrp_source_impl.cc +++ b/gr-uhd/lib/usrp_source_impl.cc @@ -154,12 +154,16 @@ namespace gr { void usrp_source_impl::set_normalized_gain(double norm_gain, size_t chan) { +#ifdef UHD_USRP_MULTI_USRP_NORMALIZED_GAIN + _dev->set_normalized_rx_gain(norm_gain, chan); +#else if (norm_gain > 1.0 || norm_gain < 0.0) { throw std::runtime_error("Normalized gain out of range, must be in [0, 1]."); } ::uhd::gain_range_t gain_range = get_gain_range(chan); double abs_gain = (norm_gain * (gain_range.stop() - gain_range.start())) + gain_range.start(); set_gain(abs_gain, chan); +#endif } double @@ -179,6 +183,9 @@ namespace gr { double usrp_source_impl::get_normalized_gain(size_t chan) { +#ifdef UHD_USRP_MULTI_USRP_NORMALIZED_GAIN + return _dev->get_normalized_rx_gain(chan); +#else ::uhd::gain_range_t gain_range = get_gain_range(chan); double norm_gain = (get_gain(chan) - gain_range.start()) / @@ -187,6 +194,7 @@ namespace gr { if (norm_gain > 1.0) return 1.0; if (norm_gain < 0.0) return 0.0; return norm_gain; +#endif } std::vector<std::string> @@ -553,6 +561,7 @@ namespace gr { gr_vector_void_star &output_items) { boost::recursive_mutex::scoped_lock lock(d_mutex); + boost::this_thread::disable_interruption disable_interrupt; //In order to allow for low-latency: //We receive all available packets without timeout. //This call can timeout under regular operation... @@ -563,6 +572,7 @@ namespace gr { _recv_timeout, true /* one packet -> minimize latency */ ); + boost::this_thread::restore_interruption restore_interrupt(disable_interrupt); //handle possible errors conditions switch(_metadata.error_code) { diff --git a/gr-utils/python/modtool/gr-newmod/CMakeLists.txt b/gr-utils/python/modtool/gr-newmod/CMakeLists.txt index bde9dc0c0f..3f316a78b4 100644 --- a/gr-utils/python/modtool/gr-newmod/CMakeLists.txt +++ b/gr-utils/python/modtool/gr-newmod/CMakeLists.txt @@ -46,6 +46,23 @@ set(VERSION_INFO_API_COMPAT 0) set(VERSION_INFO_MINOR_VERSION 0) set(VERSION_INFO_MAINT_VERSION git) +# Set cmake policies. +# This will suppress developer warnings during the cmake process that can occur +# if a newer cmake version than the minimum is used. + +if(POLICY CMP0026) + cmake_policy(SET CMP0026 OLD) +endif() +if(POLICY CMP0043) + cmake_policy(SET CMP0043 OLD) +endif() +if(POLICY CMP0045) + cmake_policy(SET CMP0045 OLD) +endif() +if(POLICY CMP0046) + cmake_policy(SET CMP0046 OLD) +endif() + ######################################################################## # Compiler specific setup ######################################################################## diff --git a/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.in b/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.in index 55336d5f1d..ef07c13205 100644 --- a/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.in +++ b/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.in @@ -1503,18 +1503,6 @@ GENERATE_XML = @enable_xml_docs@ XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that diff --git a/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.swig_doc.in b/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.swig_doc.in index 57736d7d0c..19e17dc925 100644 --- a/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.swig_doc.in +++ b/gr-utils/python/modtool/gr-newmod/docs/doxygen/Doxyfile.swig_doc.in @@ -1471,18 +1471,6 @@ GENERATE_XML = YES XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that diff --git a/gr-vocoder/CMakeLists.txt b/gr-vocoder/CMakeLists.txt index 686378f2a7..29798318e7 100644 --- a/gr-vocoder/CMakeLists.txt +++ b/gr-vocoder/CMakeLists.txt @@ -58,6 +58,7 @@ if(LIBCODEC2_FOUND) #message(STATUS "libcodec2 has 700bps mode") endif() if (LIBCODEC2_HAS_FREEDV_API) + GR_APPEND_SUBCOMPONENT("freedv") #message(STATUS "libcodec2 had FreeDV api modes: ${FREEDV_MODES}") endif() endif(LIBCODEC2_FOUND) diff --git a/gr-vocoder/examples/CMakeLists.txt b/gr-vocoder/examples/CMakeLists.txt index e5895c8d8a..20e250fe29 100644 --- a/gr-vocoder/examples/CMakeLists.txt +++ b/gr-vocoder/examples/CMakeLists.txt @@ -36,6 +36,7 @@ if(LIBCODEC2_FOUND) GR_PYTHON_INSTALL( PROGRAMS codec2_audio_loopback.py + grfreedv.grc DESTINATION ${GR_PKG_VOCODER_EXAMPLES_DIR} ) endif(LIBCODEC2_FOUND) diff --git a/gr-vocoder/examples/grfreedv.grc b/gr-vocoder/examples/grfreedv.grc new file mode 100644 index 0000000000..9f6b95d5bd --- /dev/null +++ b/gr-vocoder/examples/grfreedv.grc @@ -0,0 +1,616 @@ +<?xml version='1.0' encoding='utf-8'?> +<?grc format='1' created='3.7.9'?> +<flow_graph> + <timestamp>Wed Jun 29 19:22:27 2016</timestamp> + <block> + <key>options</key> + <param> + <key>author</key> + <value>A. MAitland Bottoms</value> + </param> + <param> + <key>window_size</key> + <value></value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>description</key> + <value>A FreeDV Modulator</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(8, 8)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>generate_options</key> + <value>qt_gui</value> + </param> + <param> + <key>hier_block_src_path</key> + <value>.:</value> + </param> + <param> + <key>id</key> + <value>grfreedv</value> + </param> + <param> + <key>max_nouts</key> + <value>0</value> + </param> + <param> + <key>qt_qss_theme</key> + <value></value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>run_command</key> + <value>{python} -u {filename}</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>thread_safe_setters</key> + <value></value> + </param> + <param> + <key>title</key> + <value>GNU Radio FreeDV</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(8, 160)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>samp_rate</value> + </param> + <param> + <key>value</key> + <value>8000</value> + </param> + </block> + <block> + <key>variable_qtgui_range</key> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>value</key> + <value>-120</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(232, 16)</value> + </param> + <param> + <key>gui_hint</key> + <value></value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>squelch</value> + </param> + <param> + <key>label</key> + <value>squelch slider</value> + </param> + <param> + <key>min_len</key> + <value>256</value> + </param> + <param> + <key>orient</key> + <value>Qt.Horizontal</value> + </param> + <param> + <key>start</key> + <value>-127</value> + </param> + <param> + <key>step</key> + <value>1</value> + </param> + <param> + <key>stop</key> + <value>128</value> + </param> + <param> + <key>rangeType</key> + <value>float</value> + </param> + <param> + <key>widget</key> + <value>counter_slider</value> + </param> + </block> + <block> + <key>audio_sink</key> + <param> + <key>alias</key> + <value></value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>device_name</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(920, 228)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>audio_sink_0</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>ok_to_block</key> + <value>True</value> + </param> + <param> + <key>samp_rate</key> + <value>samp_rate</value> + </param> + </block> + <block> + <key>audio_source</key> + <param> + <key>alias</key> + <value></value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>device_name</key> + <value>hw:2,0</value> + </param> + <param> + <key>_enabled</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(16, 325)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>audio_source_0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>num_outputs</key> + <value>1</value> + </param> + <param> + <key>ok_to_block</key> + <value>True</value> + </param> + <param> + <key>samp_rate</key> + <value>48000</value> + </param> + </block> + <block> + <key>blocks_float_to_short</key> + <param> + <key>alias</key> + <value></value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(256, 228)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>blocks_float_to_short_0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>scale</key> + <value>32768</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + </block> + <block> + <key>blocks_short_to_float</key> + <param> + <key>alias</key> + <value></value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(736, 228)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>blocks_short_to_float_0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>scale</key> + <value>32768</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + </block> + <block> + <key>blocks_wavfile_source</key> + <param> + <key>alias</key> + <value></value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>1</value> + </param> + <param> + <key>file</key> + <value>/usr/share/codec2/wav/all.wav</value> + </param> + <param> + <key>_coordinate</key> + <value>(24, 221)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>blocks_wavfile_source_0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>nchan</key> + <value>1</value> + </param> + <param> + <key>repeat</key> + <value>True</value> + </param> + </block> + <block> + <key>rational_resampler_xxx</key> + <param> + <key>alias</key> + <value></value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>decim</key> + <value>6</value> + </param> + <param> + <key>_enabled</key> + <value>0</value> + </param> + <param> + <key>fbw</key> + <value>0</value> + </param> + <param> + <key>_coordinate</key> + <value>(216, 303)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>rational_resampler_xxx_0</value> + </param> + <param> + <key>interp</key> + <value>1</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>taps</key> + <value></value> + </param> + <param> + <key>type</key> + <value>fff</value> + </param> + </block> + <block> + <key>vocoder_freedv_rx_ss</key> + <param> + <key>alias</key> + <value></value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(576, 325)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>vocoder_freedv_rx_ss_0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>mode</key> + <value>freedv_api.MODE_1600</value> + </param> + <param> + <key>squelch_thresh</key> + <value>squelch</value> + </param> + </block> + <block> + <key>vocoder_freedv_tx_ss</key> + <param> + <key>alias</key> + <value></value> + </param> + <param> + <key>comment</key> + <value></value> + </param> + <param> + <key>affinity</key> + <value></value> + </param> + <param> + <key>_enabled</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(424, 221)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + <param> + <key>id</key> + <value>vocoder_freedv_tx_ss_0</value> + </param> + <param> + <key>maxoutbuf</key> + <value>0</value> + </param> + <param> + <key>minoutbuf</key> + <value>0</value> + </param> + <param> + <key>mode</key> + <value>freedv_api.MODE_1600</value> + </param> + <param> + <key>txt_msg</key> + <value>'GNU Radio'</value> + </param> + </block> + <connection> + <source_block_id>audio_source_0</source_block_id> + <sink_block_id>rational_resampler_xxx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_float_to_short_0</source_block_id> + <sink_block_id>vocoder_freedv_tx_ss_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_short_to_float_0</source_block_id> + <sink_block_id>audio_sink_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>blocks_wavfile_source_0</source_block_id> + <sink_block_id>blocks_float_to_short_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>rational_resampler_xxx_0</source_block_id> + <sink_block_id>blocks_float_to_short_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>vocoder_freedv_rx_ss_0</source_block_id> + <sink_block_id>blocks_short_to_float_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>vocoder_freedv_tx_ss_0</source_block_id> + <sink_block_id>vocoder_freedv_rx_ss_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> +</flow_graph> diff --git a/gr-vocoder/grc/CMakeLists.txt b/gr-vocoder/grc/CMakeLists.txt index fd320545ad..eef52179cb 100644 --- a/gr-vocoder/grc/CMakeLists.txt +++ b/gr-vocoder/grc/CMakeLists.txt @@ -44,6 +44,15 @@ if(LIBCODEC2_FOUND) ) endif(LIBCODEC2_FOUND) +if(LIBCODEC2_HAS_FREEDV_API) + install(FILES + vocoder_freedv_rx_ss.xml + vocoder_freedv_tx_ss.xml + DESTINATION ${GRC_BLOCKS_DIR} + COMPONENT "vocoder_python" + ) +endif(LIBCODEC2_HAS_FREEDV_API) + if(LIBGSM_FOUND) install(FILES vocoder_gsm_fr_decode_ps.xml diff --git a/gr-vocoder/grc/CMakeLists.txt.orig b/gr-vocoder/grc/CMakeLists.txt.orig new file mode 100644 index 0000000000..fd320545ad --- /dev/null +++ b/gr-vocoder/grc/CMakeLists.txt.orig @@ -0,0 +1,53 @@ +# Copyright 2011,2016 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. + +install(FILES + vocoder_alaw_decode_bs.xml + vocoder_alaw_encode_sb.xml + vocoder_block_tree.xml + vocoder_cvsd_decode_bs.xml + vocoder_cvsd_decode.xml + vocoder_cvsd_encode_sb.xml + vocoder_cvsd_encode.xml + vocoder_g721_decode_bs.xml + vocoder_g721_encode_sb.xml + vocoder_g723_24_decode_bs.xml + vocoder_g723_24_encode_sb.xml + vocoder_g723_40_decode_bs.xml + vocoder_g723_40_encode_sb.xml + vocoder_ulaw_decode_bs.xml + vocoder_ulaw_encode_sb.xml + DESTINATION ${GRC_BLOCKS_DIR} +) + +if(LIBCODEC2_FOUND) + install(FILES + vocoder_codec2_decode_ps.xml + vocoder_codec2_encode_sp.xml + DESTINATION ${GRC_BLOCKS_DIR} + ) +endif(LIBCODEC2_FOUND) + +if(LIBGSM_FOUND) + install(FILES + vocoder_gsm_fr_decode_ps.xml + vocoder_gsm_fr_encode_sp.xml + DESTINATION ${GRC_BLOCKS_DIR} + ) +endif(LIBGSM_FOUND) diff --git a/gr-vocoder/grc/vocoder_block_tree.xml b/gr-vocoder/grc/vocoder_block_tree.xml index 07d8ba8fd1..e47af4cdd5 100644 --- a/gr-vocoder/grc/vocoder_block_tree.xml +++ b/gr-vocoder/grc/vocoder_block_tree.xml @@ -38,6 +38,8 @@ <block>vocoder_cvsd_encode_sb</block> <block>vocoder_cvsd_decode_bf</block> <block>vocoder_cvsd_encode_fb</block> + <block>vocoder_freedv_tx_ss</block> + <block>vocoder_freedv_rx_ss</block> <block>vocoder_g721_decode_bs</block> <block>vocoder_g721_encode_sb</block> <block>vocoder_g723_24_decode_bs</block> diff --git a/gr-vocoder/grc/vocoder_freedv_rx_ss.xml b/gr-vocoder/grc/vocoder_freedv_rx_ss.xml new file mode 100644 index 0000000000..14e00a0979 --- /dev/null +++ b/gr-vocoder/grc/vocoder_freedv_rx_ss.xml @@ -0,0 +1,58 @@ +<?xml version="1.0"?> +<!-- +################################################### +## FreeDV audio modem demodulator +################################################### + --> +<block> + <name>FreeDV demodulator</name> + <key>vocoder_freedv_rx_ss</key> + <import>from gnuradio import vocoder</import> + <import>from gnuradio.vocoder import freedv_api</import> + <make>vocoder.freedv_rx_ss($mode,$squelch_thresh)</make> + <callback>set_squelch_thresh($squelch_thresh)</callback> + <param> + <name>Operating Mode</name> + <key>mode</key> + <value>freedv_api.MODE_1600</value> + <type>int</type> + <option> + <name>1600</name> + <key>freedv_api.MODE_1600</key> + </option> + <option> + <name>700</name> + <key>freedv_api.MODE_700</key> + </option> + <option> + <name>700B</name> + <key>freedv_api.MODE_700B</key> + </option> + <option> + <name>2400A</name> + <key>freedv_api.MODE_2400A</key> + </option> + <option> + <name>2400B</name> + <key>freedv_api.MODE_2400B</key> + </option> + <option> + <name>800XA</name> + <key>freedv_api.MODE_800XA</key> + </option> + </param> + <param> + <name>Squelch Threshold</name> + <key>squelch_thresh</key> + <value>-100.0</value> + <type>float</type> + </param> + <sink> + <name>in</name> + <type>short</type> + </sink> + <source> + <name>out</name> + <type>short</type> + </source> +</block> diff --git a/gr-vocoder/grc/vocoder_freedv_tx_ss.xml b/gr-vocoder/grc/vocoder_freedv_tx_ss.xml new file mode 100644 index 0000000000..54a49b730f --- /dev/null +++ b/gr-vocoder/grc/vocoder_freedv_tx_ss.xml @@ -0,0 +1,57 @@ +<?xml version="1.0"?> +<!-- +################################################### +## FreeDV audio modem modulator +################################################### + --> +<block> + <name>FreeDV modulator</name> + <key>vocoder_freedv_tx_ss</key> + <import>from gnuradio import vocoder</import> + <import>from gnuradio.vocoder import freedv_api</import> + <make>vocoder.freedv_tx_ss($mode,$txt_msg)</make> + <param> + <name>Operating Mode</name> + <key>mode</key> + <value>freedv_api.MODE_1600</value> + <type>int</type> + <option> + <name>1600</name> + <key>freedv_api.MODE_1600</key> + </option> + <option> + <name>700</name> + <key>freedv_api.MODE_700</key> + </option> + <option> + <name>700B</name> + <key>freedv_api.MODE_700B</key> + </option> + <option> + <name>2400A</name> + <key>freedv_api.MODE_2400A</key> + </option> + <option> + <name>2400B</name> + <key>freedv_api.MODE_2400B</key> + </option> + <option> + <name>800XA</name> + <key>freedv_api.MODE_800XA</key> + </option> + </param> + <param> + <name>Text Message</name> + <key>txt_msg</key> + <value>'GNU Radio'</value> + <type>string</type> + </param> + <sink> + <name>in</name> + <type>short</type> + </sink> + <source> + <name>out</name> + <type>short</type> + </source> +</block> diff --git a/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt b/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt index 172f18a730..65ec5238a0 100644 --- a/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt +++ b/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt @@ -44,6 +44,15 @@ install(FILES DESTINATION ${GR_INCLUDE_DIR}/gnuradio/vocoder ) endif(LIBCODEC2_FOUND) +if(LIBCODEC2_HAS_FREEDV_API) +install(FILES + freedv_api.h + freedv_rx_ss.h + freedv_tx_ss.h + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/vocoder + COMPONENT "vocoder_devel" +) +endif(LIBCODEC2_HAS_FREEDV_API) if(LIBGSM_FOUND) install(FILES gsm_fr_decode_ps.h diff --git a/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt.orig b/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt.orig new file mode 100644 index 0000000000..172f18a730 --- /dev/null +++ b/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt.orig @@ -0,0 +1,53 @@ +# Copyright 2012,2013,2016 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. + +######################################################################## +# Install header files +######################################################################## +install(FILES + api.h + alaw_decode_bs.h + alaw_encode_sb.h + cvsd_decode_bs.h + cvsd_encode_sb.h + g721_decode_bs.h + g721_encode_sb.h + g723_24_decode_bs.h + g723_24_encode_sb.h + g723_40_decode_bs.h + g723_40_encode_sb.h + ulaw_decode_bs.h + ulaw_encode_sb.h + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/vocoder +) +if(LIBCODEC2_FOUND) +install(FILES + codec2.h + codec2_decode_ps.h + codec2_encode_sp.h + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/vocoder +) +endif(LIBCODEC2_FOUND) +if(LIBGSM_FOUND) +install(FILES + gsm_fr_decode_ps.h + gsm_fr_encode_sp.h + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/vocoder +) +endif(LIBGSM_FOUND) diff --git a/gr-vocoder/include/gnuradio/vocoder/freedv_api.h b/gr-vocoder/include/gnuradio/vocoder/freedv_api.h new file mode 100644 index 0000000000..230da4e108 --- /dev/null +++ b/gr-vocoder/include/gnuradio/vocoder/freedv_api.h @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2016 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 _VOCODER_FREEDV_H_ +#define _VOCODER_FREEDV_H_ + +#include <gnuradio/vocoder/api.h> + +extern "C" { +#include <codec2/codec2.h> +#include <codec2/freedv_api.h> +#include <codec2/modem_stats.h> +} + +namespace gr { + namespace vocoder { + + class VOCODER_API freedv_api { + public: + + enum freedv_modes { +#ifdef FREEDV_MODE_1600 + MODE_1600 = FREEDV_MODE_1600, +#endif +#ifdef FREEDV_MODE_700 + MODE_700 = FREEDV_MODE_700, +#endif +#ifdef FREEDV_MODE_700B + MODE_700B = FREEDV_MODE_700B, +#endif +#ifdef FREEDV_MODE_2400A + MODE_2400A = FREEDV_MODE_2400A, +#endif +#ifdef FREEDV_MODE_2400B + MODE_2400B = FREEDV_MODE_2400B, +#endif +#ifdef FREEDV_MODE_800XA + MODE_800XA = FREEDV_MODE_800XA, +#endif + }; + + private: + + }; + + } /* namespace vocoder */ +} /* namespace gr */ + +#endif /* _VOCODER_FREEDV_H_ */ diff --git a/gr-vocoder/include/gnuradio/vocoder/freedv_rx_ss.h b/gr-vocoder/include/gnuradio/vocoder/freedv_rx_ss.h new file mode 100644 index 0000000000..a6568dee7d --- /dev/null +++ b/gr-vocoder/include/gnuradio/vocoder/freedv_rx_ss.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2016 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_VOCODER_FREEDV_RX_H +#define INCLUDED_VOCODER_FREEDV_RX_H + +#include <gnuradio/vocoder/api.h> +#include <gnuradio/vocoder/freedv_api.h> +#include <gnuradio/block.h> + +namespace gr { + namespace vocoder { + + /*! + * \brief FreeDV demodulator + * \ingroup audio_blk + * + * Input: 16-bit short values of an audio signal with sampling rate 8 kHz. + * + * Output: 16-bit short values of an audio signal with sampling rate 8 kHz. + * + * See also gr::vocoder::freedv_tx_ss. + */ + class VOCODER_API freedv_rx_ss : virtual public gr::block + { + public: + typedef boost::shared_ptr<freedv_rx_ss> sptr; + + /*! + * \brief Make FreeDV modem demodulator block. + * + * \param mode Operating Mode designation + * \param squelch_thresh FreeDV modem squelch threshold value + */ + static sptr make(int mode=freedv_api::MODE_1600, float squelch_thresh=-100.0); + + virtual void set_squelch_thresh(float squelch_thresh) = 0; + virtual float squelch_thresh() = 0; + }; + + } /* namespace vocoder */ +} /* namespace gr */ + +#endif /* INCLUDED_VOCODER_FREEDV_RX_H */ diff --git a/gr-vocoder/include/gnuradio/vocoder/freedv_tx_ss.h b/gr-vocoder/include/gnuradio/vocoder/freedv_tx_ss.h new file mode 100644 index 0000000000..0e80d78bfb --- /dev/null +++ b/gr-vocoder/include/gnuradio/vocoder/freedv_tx_ss.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2016 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_VOCODER_FREEDV_TX_H +#define INCLUDED_VOCODER_FREEDV_TX_H + +#include <gnuradio/vocoder/api.h> +#include <gnuradio/vocoder/freedv_api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + namespace vocoder { + + /*! + * \brief FreeDV modulator + * \ingroup audio_blk + * + * Input: Speech (audio) signal as 16-bit shorts, sampling rate 8 kHz. + * + * Output: Signal (audio) as 16-bit shorts, sampling rate 8 kHz. + * + */ + class VOCODER_API freedv_tx_ss : virtual public gr::sync_block + { + public: + typedef boost::shared_ptr<freedv_tx_ss> sptr; + + /*! + * \brief Make FreeDV Modem modulator block. + * + * \param mode Operating Mode designation + * \param msg_txt Low Rate message text (callsign, location) + */ + static sptr make(int mode=freedv_api::MODE_1600,const std::string msg_txt="GNU Radio"); + }; + + } /* namespace vocoder */ +} /* namespace gr */ + +#endif /* INCLUDED_VOCODER_FREEDV_TX_H */ diff --git a/gr-vocoder/lib/CMakeLists.txt b/gr-vocoder/lib/CMakeLists.txt index 5e806a2c2c..e26cb1820a 100644 --- a/gr-vocoder/lib/CMakeLists.txt +++ b/gr-vocoder/lib/CMakeLists.txt @@ -61,6 +61,13 @@ if(LIBCODEC2_FOUND) codec2_encode_sp_impl.cc ) endif(LIBCODEC2_FOUND) +if(LIBCODEC2_HAS_FREEDV_API) + list(APPEND gr_vocoder_sources + freedv_api.cc + freedv_rx_ss_impl.cc + freedv_tx_ss_impl.cc + ) +endif(LIBCODEC2_HAS_FREEDV_API) if(LIBGSM_FOUND) list(APPEND gr_vocoder_sources gsm_fr_decode_ps_impl.cc diff --git a/gr-vocoder/lib/freedv_api.cc b/gr-vocoder/lib/freedv_api.cc new file mode 100644 index 0000000000..063a6bb9f0 --- /dev/null +++ b/gr-vocoder/lib/freedv_api.cc @@ -0,0 +1,33 @@ +/* -*- c++ -*- */ +/* + * Copyright 2016 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 <gnuradio/vocoder/freedv_api.h> + +namespace gr { + namespace vocoder { + + } /* namespace vocoder */ +} /* namespace gr */ diff --git a/gr-vocoder/lib/freedv_rx_ss_impl.cc b/gr-vocoder/lib/freedv_rx_ss_impl.cc new file mode 100644 index 0000000000..748a5c10aa --- /dev/null +++ b/gr-vocoder/lib/freedv_rx_ss_impl.cc @@ -0,0 +1,146 @@ +/* -*- c++ -*- */ +/* + * Copyright 2016 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 "freedv_rx_ss_impl.h" + +#include <gnuradio/io_signature.h> +#include <stdexcept> +#include <assert.h> + +extern "C" { + void put_next_rx_char(void *callback_state, char c) { + struct freedv_rx_callback_state* pstate; + + pstate = (struct freedv_rx_callback_state*) callback_state; + if (pstate->ftxt != NULL) { + //fprintf(pstate->ftxt, "%c\n", c); + } + return; + } +} + + +namespace gr { + namespace vocoder { + + freedv_rx_ss::sptr + freedv_rx_ss::make(int mode, float squelch_thresh) + { + return gnuradio::get_initial_sptr + (new freedv_rx_ss_impl(mode, squelch_thresh)); + } + + freedv_rx_ss_impl::freedv_rx_ss_impl (int mode, float squelch_thresh) + : gr::block("vocoder_freedv_rx_ss", + io_signature::make(1, 1, sizeof(short)), + io_signature::make(1, 1, sizeof(short))), + d_mode(mode), d_squelch_thresh(squelch_thresh) + { + if((d_freedv = freedv_open(mode)) == NULL) + throw std::runtime_error("freedv_rx_ss_impl: freedv_open failed"); + freedv_set_snr_squelch_thresh(d_freedv, d_squelch_thresh); + freedv_set_squelch_en(d_freedv, 0); + freedv_set_callback_txt(d_freedv, put_next_rx_char, NULL, (void *) &d_cb_state); + d_speech_samples = freedv_get_n_speech_samples(d_freedv); + d_max_modem_samples = freedv_get_n_max_modem_samples(d_freedv); + d_nin = freedv_nin(d_freedv); + set_output_multiple(d_max_modem_samples); + } + + freedv_rx_ss_impl::~freedv_rx_ss_impl() + { + int total_bits; + int total_bit_errors; + + if (freedv_get_test_frames(d_freedv)) { + total_bits = freedv_get_total_bits(d_freedv); + total_bit_errors = freedv_get_total_bit_errors(d_freedv); + fprintf(stderr, "bits: %d errors: %d BER: %3.2f\n", total_bits, total_bit_errors, (1.0*total_bit_errors)/total_bits); + } + freedv_close(d_freedv); + } + + void + freedv_rx_ss_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] = std::max(d_nin, noutput_items); + } + + int + freedv_rx_ss_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + short *in = (short *) input_items[0]; + short *out = (short *) output_items[0]; + + int in_offset = 0, out_offset = 0; + + while ((noutput_items - out_offset) >= d_max_modem_samples + && (ninput_items[0] - in_offset) >= d_nin) { + d_nout = freedv_rx(d_freedv, out + out_offset, in + in_offset); + out_offset += d_nout; + in_offset += d_nin; + d_nin = freedv_nin(d_freedv); + } + + freedv_get_modem_stats(d_freedv, &d_sync, &d_snr_est); + freedv_get_modem_extended_stats(d_freedv, &d_stats); + d_total_bit_errors = freedv_get_total_bit_errors(d_freedv); + + consume_each(in_offset); + return out_offset; + } + + void put_next_rx_proto(void *callback_state,char *proto_bits) { + return; + } + + void datarx(void *callback_state, unsigned char *packet, size_t size) { + return; + } + + void datatx(void *callback_state, unsigned char *packet, size_t *size) { + return; + } + + void freedv_rx_ss_impl::set_squelch_thresh(float squelch_thresh) + { + gr::thread::scoped_lock l(d_setlock); + d_squelch_thresh = squelch_thresh; + freedv_set_snr_squelch_thresh(d_freedv, d_squelch_thresh); + } + + float freedv_rx_ss_impl::squelch_thresh() { + return(d_squelch_thresh); + } + + } /* namespace vocoder */ +} /* namespace gr */ diff --git a/gr-vocoder/lib/freedv_rx_ss_impl.h b/gr-vocoder/lib/freedv_rx_ss_impl.h new file mode 100644 index 0000000000..acc49d9d82 --- /dev/null +++ b/gr-vocoder/lib/freedv_rx_ss_impl.h @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2016 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_VOCODER_FREEDV_RX_SS_IMPL_H +#define INCLUDED_VOCODER_FREEDV_RX_SS_IMPL_H + +#include <gnuradio/vocoder/freedv_rx_ss.h> + +extern "C" { + struct freedv_rx_callback_state { + FILE *ftxt; + }; + static void put_next_rx_char(void *callback_state, char c); + void put_next_rx_proto(void *callback_state,char *proto_bits); + void datarx(void *callback_state, unsigned char *packet, size_t size); + void datatx(void *callback_state, unsigned char *packet, size_t *size); +} + +namespace gr { + namespace vocoder { + + class freedv_rx_ss_impl : public freedv_rx_ss + { + private: + short *d_speech_out; + short *d_demod_in; + struct freedv *d_freedv; + int d_nin, d_nout, d_frame; + struct freedv_rx_callback_state d_cb_state; + struct MODEM_STATS d_stats; + int d_mode; + int d_sync; + int d_total_bits; + int d_total_bit_errors; + float d_snr_est; + float d_squelch_thresh; + int d_speech_samples; + int d_max_modem_samples; + float d_clock_offset; + int d_use_codecrx; + struct CODEC2 *d_c2 = NULL; + + public: + freedv_rx_ss_impl(int mode, float squelch_thresh); + ~freedv_rx_ss_impl(); + + void set_squelch_thresh(float squelch_thresh); + float squelch_thresh(); + + // 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 vocoder */ +} /* namespace gr */ + +#endif /* INCLUDED_VOCODER_FREEDV_RX_SS_IMPL_H */ diff --git a/gr-vocoder/lib/freedv_tx_ss_impl.cc b/gr-vocoder/lib/freedv_tx_ss_impl.cc new file mode 100644 index 0000000000..a375510050 --- /dev/null +++ b/gr-vocoder/lib/freedv_tx_ss_impl.cc @@ -0,0 +1,98 @@ +/* -*- c++ -*- */ +/* + * Copyright 2016 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 "freedv_tx_ss_impl.h" + +#include <gnuradio/io_signature.h> +#include <stdexcept> +#include <iostream> +#include <iomanip> + +extern "C" { + char + get_next_tx_char(void *callback_state) + { + char c; + struct freedv_tx_callback_state* pstate; + + pstate = (struct freedv_tx_callback_state*)callback_state; + c = *pstate->ptx_str++; + + if (*pstate->ptx_str == 0) { + pstate->ptx_str = pstate->tx_str; + c = 0x0d; // FreeDV uses Carriage Return termination + } + + return c; + } +} + +namespace gr { + namespace vocoder { + + freedv_tx_ss::sptr + freedv_tx_ss::make(int mode, const std::string msg_txt) + { + return gnuradio::get_initial_sptr + (new freedv_tx_ss_impl(mode, msg_txt)); + } + + freedv_tx_ss_impl::freedv_tx_ss_impl(int mode, const std::string msg_txt) + : sync_block("vocoder_freedv_tx_ss", + io_signature::make(1, 1, sizeof(short)), + io_signature::make(1, 1, sizeof(short))), + d_mode(mode), d_msg_text(msg_txt) + { + if((d_freedv = freedv_open(mode)) == NULL) + throw std::runtime_error("freedv_tx_ss_impl: freedv_open failed"); + snprintf(d_cb_state.tx_str,79,"%s",d_msg_text.c_str()); + d_cb_state.ptx_str = d_cb_state.tx_str; + freedv_set_callback_txt(d_freedv, NULL, get_next_tx_char, (void *) &d_cb_state); + d_nom_modem_samples = freedv_get_n_nom_modem_samples(d_freedv); + set_output_multiple(d_nom_modem_samples); + } + + freedv_tx_ss_impl::~freedv_tx_ss_impl() + { + freedv_close(d_freedv); + } + + int + freedv_tx_ss_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + short *in = (short*)input_items[0]; + short *out = (short*)output_items[0]; + int i; + + for(i=0;i<(noutput_items/d_nom_modem_samples);i++) + freedv_tx(d_freedv, &(out[i*d_nom_modem_samples]), &(in[i*d_nom_modem_samples])); + return noutput_items; + } + + } /* namespace vocoder */ +} /* namespace gr */ diff --git a/gr-vocoder/lib/freedv_tx_ss_impl.h b/gr-vocoder/lib/freedv_tx_ss_impl.h new file mode 100644 index 0000000000..a023b67f5b --- /dev/null +++ b/gr-vocoder/lib/freedv_tx_ss_impl.h @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2016 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_VOCODER_FREEDV_TX_SS_IMPL_H +#define INCLUDED_VOCODER_FREEDV_TX_SS_IMPL_H + +#include <gnuradio/vocoder/freedv_tx_ss.h> + +extern "C" { + struct freedv_tx_callback_state { + char tx_str[80]; + char *ptx_str; + int calls; + }; + char get_next_tx_char(void *callback_state); + void get_next_proto(void *callback_state,char *proto_bits); + void datarx(void *callback_state, unsigned char *packet, size_t size); + void datatx(void *callback_state, unsigned char *packet, size_t *size); +} + +namespace gr { + namespace vocoder { + + class freedv_tx_ss_impl : public freedv_tx_ss + { + private: + short *d_speech_in; + short *d_mod_out; + struct freedv_tx_callback_state d_cb_state; + struct freedv *d_freedv; + int d_mode; + float d_squelch_thresh; + int d_speech_samples; + int d_nom_modem_samples; + int d_use_codectx; + int d_use_datatx; + std::string d_msg_text; + struct CODEC2 *d_c2; + + public: + freedv_tx_ss_impl(int mode, const std::string txt_msg); + ~freedv_tx_ss_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 vocoder */ +} /* namespace gr */ + +#endif /* INCLUDED_VOCODER_FREEDV_TX_SS_IMPL_H */ diff --git a/gr-vocoder/swig/CMakeLists.txt b/gr-vocoder/swig/CMakeLists.txt index 8597fb115c..60f2f47329 100644 --- a/gr-vocoder/swig/CMakeLists.txt +++ b/gr-vocoder/swig/CMakeLists.txt @@ -37,6 +37,10 @@ if(LIBCODEC2_FOUND) list(APPEND GR_SWIG_FLAGS "-DLIBCODEC2_FOUND") endif(LIBCODEC2_FOUND) +if(LIBCODEC2_HAS_FREEDV_API) + list(APPEND GR_SWIG_FLAGS "-DLIBCODEC2_HAS_FREEDV_API") +endif(LIBCODEC2_HAS_FREEDV_API) + if(LIBGSM_FOUND) list(APPEND GR_SWIG_FLAGS "-DLIBGSM_FOUND") endif(LIBGSM_FOUND) diff --git a/gr-vocoder/swig/vocoder_swig.i b/gr-vocoder/swig/vocoder_swig.i index 43d0d1f79b..1bf451539d 100644 --- a/gr-vocoder/swig/vocoder_swig.i +++ b/gr-vocoder/swig/vocoder_swig.i @@ -85,6 +85,25 @@ GR_SWIG_BLOCK_MAGIC2(vocoder, codec2_decode_ps); GR_SWIG_BLOCK_MAGIC2(vocoder, codec2_encode_sp); #endif +#ifdef LIBCODEC2_HAS_FREEDV_API +%{ +#include <codec2/freedv_api.h> +#include "gnuradio/vocoder/freedv_api.h" +#include "gnuradio/vocoder/freedv_rx_ss.h" +#include "gnuradio/vocoder/freedv_tx_ss.h" +%} + +%ignore freedv_set_smooth_symbols; +%ignore freedv_set_clip; +%include <codec2/freedv_api.h> +%include "gnuradio/vocoder/freedv_api.h" +%include "gnuradio/vocoder/freedv_rx_ss.h" +%include "gnuradio/vocoder/freedv_tx_ss.h" + +GR_SWIG_BLOCK_MAGIC2(vocoder, freedv_rx_ss); +GR_SWIG_BLOCK_MAGIC2(vocoder, freedv_tx_ss); +#endif + #ifdef LIBGSM_FOUND %{ #include "gnuradio/vocoder/gsm_fr_decode_ps.h" diff --git a/grc/core/Block.py b/grc/core/Block.py index 9a1d72c2de..bca17d458a 100644 --- a/grc/core/Block.py +++ b/grc/core/Block.py @@ -719,10 +719,11 @@ class EPyBlock(Block): iter_ports = iter(ports) ports_new = [] port_current = next(iter_ports, None) - for key, port_type in port_specs: + for key, port_type, vlen in port_specs: reuse_port = ( port_current is not None and port_current.get_type() == port_type and + port_current.get_vlen() == vlen and (key.isdigit() or port_current.key == key) ) if reuse_port: @@ -733,6 +734,8 @@ class EPyBlock(Block): if port_type == 'message': n['name'] = key n['optional'] = '1' + if vlen > 1: + n['vlen'] = str(vlen) port = port_factory(self, direction=direction, **n) ports_new.append(port) # replace old port list with new one diff --git a/grc/core/generator/Generator.py b/grc/core/generator/Generator.py index 8b073293ce..7f0caea49d 100644 --- a/grc/core/generator/Generator.py +++ b/grc/core/generator/Generator.py @@ -245,7 +245,7 @@ class TopBlockGenerator(object): } # Build the template t = Template(open(FLOW_GRAPH_TEMPLATE, 'r').read(), namespace) - output.append((self.file_path, str(t))) + output.append((self.file_path, "\n".join(line.rstrip() for line in str(t).split("\n")))) return output diff --git a/grc/core/utils/epy_block_io.py b/grc/core/utils/epy_block_io.py index fc631203e3..823116adb9 100644 --- a/grc/core/utils/epy_block_io.py +++ b/grc/core/utils/epy_block_io.py @@ -22,14 +22,15 @@ BlockIO = collections.namedtuple('BlockIO', 'name cls params sinks sources doc c def _ports(sigs, msgs): ports = list() for i, dtype in enumerate(sigs): - port_type = TYPE_MAP.get(dtype.name, None) + port_type = TYPE_MAP.get(dtype.base.name, None) if not port_type: raise ValueError("Can't map {0!r} to GRC port type".format(dtype)) - ports.append((str(i), port_type)) + vlen = dtype.shape[0] if len(dtype.shape) > 0 else 1 + ports.append((str(i), port_type, vlen)) for msg_key in msgs: if msg_key == 'system': continue - ports.append((msg_key, 'message')) + ports.append((msg_key, 'message', 1)) return ports @@ -127,4 +128,3 @@ class blk(gr.sync_block): """ from pprint import pprint pprint(dict(extract(blk_code)._asdict())) - |