diff options
Diffstat (limited to 'gnuradio-core/src/lib/io')
-rw-r--r-- | gnuradio-core/src/lib/io/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gnuradio-core/src/lib/io/gr_message_burst_source.cc | 144 | ||||
-rw-r--r-- | gnuradio-core/src/lib/io/gr_message_burst_source.h | 71 | ||||
-rw-r--r-- | gnuradio-core/src/lib/io/gr_message_burst_source.i | 38 | ||||
-rw-r--r-- | gnuradio-core/src/lib/io/gr_tagged_file_sink.cc | 2 | ||||
-rw-r--r-- | gnuradio-core/src/lib/io/gr_udp_source.cc | 10 | ||||
-rw-r--r-- | gnuradio-core/src/lib/io/gri_wavfile.cc | 136 | ||||
-rw-r--r-- | gnuradio-core/src/lib/io/gri_wavfile.h | 27 | ||||
-rw-r--r-- | gnuradio-core/src/lib/io/io.i | 2 |
9 files changed, 311 insertions, 120 deletions
diff --git a/gnuradio-core/src/lib/io/CMakeLists.txt b/gnuradio-core/src/lib/io/CMakeLists.txt index af9d7583c..3dea13396 100644 --- a/gnuradio-core/src/lib/io/CMakeLists.txt +++ b/gnuradio-core/src/lib/io/CMakeLists.txt @@ -87,6 +87,7 @@ set(gr_core_io_triple_threats gr_file_descriptor_source gr_message_sink gr_message_source + gr_message_burst_source microtune_xxxx_eval_board microtune_4702_eval_board microtune_4937_eval_board diff --git a/gnuradio-core/src/lib/io/gr_message_burst_source.cc b/gnuradio-core/src/lib/io/gr_message_burst_source.cc new file mode 100644 index 000000000..e9e2dfd4d --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_message_burst_source.cc @@ -0,0 +1,144 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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 <gr_message_burst_source.h> +#include <gr_io_signature.h> +#include <cstdio> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdexcept> +#include <string.h> +#include <gr_tags.h> + +// public constructor that returns a shared_ptr + +gr_message_burst_source_sptr +gr_make_message_burst_source(size_t itemsize, int msgq_limit) +{ + return gnuradio::get_initial_sptr(new gr_message_burst_source(itemsize, msgq_limit)); +} + +// public constructor that takes existing message queue +gr_message_burst_source_sptr +gr_make_message_burst_source(size_t itemsize, gr_msg_queue_sptr msgq) +{ + return gnuradio::get_initial_sptr(new gr_message_burst_source(itemsize, msgq)); +} + +gr_message_burst_source::gr_message_burst_source (size_t itemsize, int msgq_limit) + : gr_sync_block("message_burst_source", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, itemsize)), + d_itemsize(itemsize), d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false) +{ + std::stringstream id; + id << name() << unique_id(); + d_me = pmt::pmt_string_to_symbol(id.str()); +} + +gr_message_burst_source::gr_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq) + : gr_sync_block("message_burst_source", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, itemsize)), + d_itemsize(itemsize), d_msgq(msgq), d_msg_offset(0), d_eof(false) +{ + std::stringstream id; + id << name() << unique_id(); + d_me = pmt::pmt_string_to_symbol(id.str()); +} + +gr_message_burst_source::~gr_message_burst_source() +{ +} + +int +gr_message_burst_source::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + char *out = (char *) output_items[0]; + int nn = 0; + + uint64_t abs_sample_count = nitems_written(0); + + while (nn < noutput_items){ + if (d_msg){ + // + // Consume whatever we can from the current message + // + + int mm = std::min(noutput_items - nn, (int)((d_msg->length() - d_msg_offset) / d_itemsize)); + memcpy (out, &(d_msg->msg()[d_msg_offset]), mm * d_itemsize); + + nn += mm; + out += mm * d_itemsize; + d_msg_offset += mm * d_itemsize; + assert(d_msg_offset <= d_msg->length()); + + if (d_msg_offset == d_msg->length()){ + if (d_msg->type() == 1) // type == 1 sets EOF + d_eof = true; + d_msg.reset(); + //tag end of burst + add_item_tag(0, //stream ID + abs_sample_count+nn-1, //sample number + pmt::pmt_string_to_symbol("tx_eob"), + pmt::pmt_from_bool(1), + d_me //block src id + ); + } + } + else { + // + // No current message + // + if (d_msgq->empty_p() && nn > 0){ // no more messages in the queue, return what we've got + break; + } + + if (d_eof) + return -1; + + d_msg = d_msgq->delete_head(); // block, waiting for a message + d_msg_offset = 0; + //tag start of burst + add_item_tag(0, //stream ID + abs_sample_count+nn, //sample number + pmt::pmt_string_to_symbol("tx_sob"), + pmt::pmt_from_bool(1), + d_me //block src id + ); + + + if ((d_msg->length() % d_itemsize) != 0) + throw std::runtime_error("msg length is not a multiple of d_itemsize"); + } + } + + return nn; +} diff --git a/gnuradio-core/src/lib/io/gr_message_burst_source.h b/gnuradio-core/src/lib/io/gr_message_burst_source.h new file mode 100644 index 000000000..63e220113 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_message_burst_source.h @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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_GR_MESSAGE_BURST_SOURCE_H +#define INCLUDED_GR_MESSAGE_BURST_SOURCE_H + +#include <gr_core_api.h> +#include <gr_sync_block.h> +#include <gr_message.h> +#include <gr_msg_queue.h> + +class gr_message_burst_source; +typedef boost::shared_ptr<gr_message_burst_source> gr_message_burst_source_sptr; + +GR_CORE_API gr_message_burst_source_sptr gr_make_message_burst_source (size_t itemsize, int msgq_limit=0); +GR_CORE_API gr_message_burst_source_sptr gr_make_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq); + +/*! + * \brief Turn received messages into a stream and tag them for UHD to send. + * \ingroup source_blk + */ +class GR_CORE_API gr_message_burst_source : public gr_sync_block +{ + private: + size_t d_itemsize; + gr_msg_queue_sptr d_msgq; + gr_message_sptr d_msg; + unsigned d_msg_offset; + bool d_eof; + + pmt::pmt_t d_me; + + friend GR_CORE_API gr_message_burst_source_sptr + gr_make_message_burst_source(size_t itemsize, int msgq_limit); + friend GR_CORE_API gr_message_burst_source_sptr + gr_make_message_burst_source(size_t itemsize, gr_msg_queue_sptr msgq); + + protected: + gr_message_burst_source (size_t itemsize, int msgq_limit); + gr_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq); + + public: + ~gr_message_burst_source (); + + gr_msg_queue_sptr msgq() const { return d_msgq; } + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_gr_message_burst_source_H */ diff --git a/gnuradio-core/src/lib/io/gr_message_burst_source.i b/gnuradio-core/src/lib/io/gr_message_burst_source.i new file mode 100644 index 000000000..f7ad840c2 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_message_burst_source.i @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,message_burst_source); + +gr_message_burst_source_sptr gr_make_message_burst_source (size_t itemsize, int msgq_limit=0); +gr_message_burst_source_sptr gr_make_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq); + +class gr_message_burst_source : public gr_sync_block +{ + protected: + gr_message_burst_source (size_t itemsize, int msgq_limit); + gr_message_burst_source (size_t itemsize, gr_msg_queue_sptr msgq); + + public: + ~gr_message_burst_source (); + + gr_msg_queue_sptr msgq() const; +}; diff --git a/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc b/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc index d69892762..6d642088e 100644 --- a/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc +++ b/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc @@ -143,7 +143,7 @@ gr_tagged_file_sink::work (int noutput_items, std::stringstream filename; filename.setf(std::ios::fixed, std::ios::floatfield); filename.precision(8); - filename << "file" << d_n << "_" << d_timeval << ".dat"; + filename << "file" << unique_id() << "_" << d_n << "_" << d_timeval << ".dat"; d_n++; int fd; diff --git a/gnuradio-core/src/lib/io/gr_udp_source.cc b/gnuradio-core/src/lib/io/gr_udp_source.cc index af41159ee..eca8e89d0 100644 --- a/gnuradio-core/src/lib/io/gr_udp_source.cc +++ b/gnuradio-core/src/lib/io/gr_udp_source.cc @@ -269,8 +269,9 @@ gr_udp_source::work (int noutput_items, else if(r == 0 ) { // timed out if( d_wait ) { // Allow boost thread interrupt, then try again - boost::this_thread::interruption_point(); - continue; + //boost::this_thread::interruption_point(); + //continue; + return 0; } else return -1; @@ -294,8 +295,9 @@ gr_udp_source::work (int noutput_items, if( d_wait ) { // Allow boost thread interrupt, then try again - boost::this_thread::interruption_point(); - continue; + //boost::this_thread::interruption_point(); + //continue; + return 0; } else return -1; diff --git a/gnuradio-core/src/lib/io/gri_wavfile.cc b/gnuradio-core/src/lib/io/gri_wavfile.cc index e316a0825..277e6b7b0 100644 --- a/gnuradio-core/src/lib/io/gri_wavfile.cc +++ b/gnuradio-core/src/lib/io/gri_wavfile.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2008 Free Software Foundation, Inc. + * Copyright 2004,2008,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -27,110 +27,45 @@ #include <gri_wavfile.h> #include <cstring> #include <stdint.h> +#include <boost/detail/endian.hpp> //BOOST_BIG_ENDIAN # define VALID_COMPRESSION_TYPE 0x0001 -// WAV files are always little-endian, so we need some byte switching macros - -// FIXME: Use libgruel versions - -#ifdef WORDS_BIGENDIAN - -#ifdef HAVE_BYTESWAP_H -#include <byteswap.h> -#else -#warning Using non-portable code (likely wrong other than ILP32). - -static inline short int -bswap_16 (unsigned short int x) -{ - return ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)); -} - -static inline unsigned int -bswap_32 (unsigned int x) -{ - return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) \ - | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)); -} -#endif // HAVE_BYTESWAP_H - -static inline uint32_t -host_to_wav(uint32_t x) -{ - return bswap_32(x); -} - -static inline uint16_t -host_to_wav(uint16_t x) -{ - return bswap_16(x); -} - -static inline int16_t -host_to_wav(int16_t x) -{ - return bswap_16(x); -} +// Basically, this is the opposite of htonx() and ntohx() +// Define host to/from worknet (little endian) short and long +#ifdef BOOST_BIG_ENDIAN -static inline uint32_t -wav_to_host(uint32_t x) -{ - return bswap_32(x); -} + static inline uint16_t __gri_wav_bs16(uint16_t x) + { + return (x>>8) | (x<<8); + } -static inline uint16_t -wav_to_host(uint16_t x) -{ - return bswap_16(x); -} + static inline uint32_t __gri_wav_bs32(uint32_t x) + { + return (uint32_t(__gri_wav_bs16(uint16_t(x&0xfffful)))<<16) | (__gri_wav_bs16(uint16_t(x>>16))); + } -static inline int16_t -wav_to_host(int16_t x) -{ - return bswap_16(x); -} + #define htowl(x) __gri_wav_bs32(x) + #define wtohl(x) __gri_wav_bs32(x) + #define htows(x) __gri_wav_bs16(x) + #define wtohs(x) __gri_wav_bs16(x) #else -static inline uint32_t -host_to_wav(uint32_t x) -{ - return x; -} - -static inline uint16_t -host_to_wav(uint16_t x) -{ - return x; -} - -static inline int16_t -host_to_wav(int16_t x) -{ - return x; -} - -static inline uint32_t -wav_to_host(uint32_t x) -{ - return x; -} - -static inline uint16_t -wav_to_host(uint16_t x) -{ - return x; -} - -static inline int16_t -wav_to_host(int16_t x) -{ - return x; -} + #define htowl(x) uint32_t(x) + #define wtohl(x) uint32_t(x) + #define htows(x) uint16_t(x) + #define wtohs(x) uint16_t(x) -#endif // WORDS_BIGENDIAN +#endif // BOOST_BIG_ENDIAN +// WAV files are always little-endian, so we need some byte switching macros +static inline uint32_t host_to_wav(uint32_t x) { return htowl(x); } +static inline uint16_t host_to_wav(uint16_t x) { return htows(x); } +static inline int16_t host_to_wav(int16_t x) { return htows(x); } +static inline uint32_t wav_to_host(uint32_t x) { return wtohl(x); } +static inline uint16_t wav_to_host(uint16_t x) { return wtohs(x); } +static inline int16_t wav_to_host(int16_t x) { return wtohs(x); } bool gri_wavheader_parse(FILE *fp, @@ -225,12 +160,15 @@ gri_wavheader_parse(FILE *fp, short int gri_wav_read_sample(FILE *fp, int bytes_per_sample) { - int16_t buf = 0; - size_t fresult; + int16_t buf_16bit; - fresult = fread(&buf, bytes_per_sample, 1, fp); - - return (short) wav_to_host(buf); + if(!fread(&buf_16bit, bytes_per_sample, 1, fp)) { + return 0; + } + if(bytes_per_sample == 1) { + return (short) buf_16bit; + } + return (short)wav_to_host(buf_16bit); } diff --git a/gnuradio-core/src/lib/io/gri_wavfile.h b/gnuradio-core/src/lib/io/gri_wavfile.h index c757be26b..16280e34a 100644 --- a/gnuradio-core/src/lib/io/gri_wavfile.h +++ b/gnuradio-core/src/lib/io/gri_wavfile.h @@ -29,20 +29,15 @@ /*! * \brief Read signal information from a given WAV file. * - * \p fp File pointer to an opened, empty file. - * \p sample_rate Stores the sample rate [S/s] - * \p nchans Number of channels - * \p bytes_per_sample Bytes per sample, can either be 1 or 2 (corresponding to - * 8 or 16 bit samples, respectively) - * \p first_sample_pos Number of the first byte containing a sample. Use this - * with fseek() to jump from the end of the file to the first sample - * when in repeat mode. - * \p samples_per_chan Number of samples per channel - * \p normalize_fac The normalization factor with which you need to divide the - * integer values of the samples to get them within [-1;1] - * \p normalize_shift The value by which the sample values need to be shifted - * after normalization (reason being, 8-bit WAV files store samples as - * unsigned char and 16-bit as signed short int) + * \param[in] fp File pointer to an opened, empty file. + * \param[out] sample_rate Stores the sample rate [S/s] + * \param[out] nchans Number of channels + * \param[out] bytes_per_sample Bytes per sample, can either be 1 or 2 (corresponding o + * 8 or 16 bit samples, respectively) + * \param[out] first_sample_pos Number of the first byte containing a sample. Use this + * with fseek() to jump from the end of the file to the + * first sample when in repeat mode. + * \param[out] samples_per_chan Number of samples per channel * \return True on a successful read, false if the file could not be read or is * not a valid WAV file. */ @@ -94,8 +89,8 @@ gri_wav_write_sample(FILE *fp, short int sample, int bytes_per_sample); * shouldn't happen), you need to fseek() to the end of the file (or * whereever). * - * \p fp File pointer to an open WAV file with a blank header - * \p byte_count Length of all samples written to the file in bytes. + * \param[in] fp File pointer to an open WAV file with a blank header + * \param[in] byte_count Length of all samples written to the file in bytes. */ bool gri_wavheader_complete(FILE *fp, unsigned int byte_count); diff --git a/gnuradio-core/src/lib/io/io.i b/gnuradio-core/src/lib/io/io.i index eab1346f1..5cd352905 100644 --- a/gnuradio-core/src/lib/io/io.i +++ b/gnuradio-core/src/lib/io/io.i @@ -38,6 +38,7 @@ #include <gr_oscope_sink_f.h> #include <ppio.h> #include <gr_message_source.h> +#include <gr_message_burst_source.h> #include <gr_message_sink.h> #include <gr_udp_sink.h> #include <gr_udp_source.h> @@ -59,6 +60,7 @@ %include "gr_oscope_sink.i" %include "ppio.i" %include "gr_message_source.i" +%include "gr_message_burst_source.i" %include "gr_message_sink.i" %include "gr_udp_sink.i" %include "gr_udp_source.i" |