diff options
author | Dimitri Stolnikov <horiz0n@gmx.net> | 2012-04-06 15:29:14 +0200 |
---|---|---|
committer | Dimitri Stolnikov <horiz0n@gmx.net> | 2012-04-06 15:29:14 +0200 |
commit | 0efd28de6bc86c3e474cfad70d1e5889575224a7 (patch) | |
tree | d3d12127a6315f026505629bec961d32696271e6 /lib |
initial commit
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CMakeLists.txt | 57 | ||||
-rw-r--r-- | lib/osmosdr_ranges.cc | 163 | ||||
-rw-r--r-- | lib/osmosdr_sink_c_impl.cc | 69 | ||||
-rw-r--r-- | lib/osmosdr_sink_c_impl.h | 41 | ||||
-rw-r--r-- | lib/osmosdr_source_c_impl.cc | 136 | ||||
-rw-r--r-- | lib/osmosdr_source_c_impl.h | 60 | ||||
-rw-r--r-- | lib/rtl_source_c.cc | 229 | ||||
-rw-r--r-- | lib/rtl_source_c.h | 104 |
8 files changed, 859 insertions, 0 deletions
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 0000000..40c0a58 --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1,57 @@ +# Copyright 2011 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. + +######################################################################## +# Setup library +######################################################################## +include(GrPlatform) #define LIB_SUFFIX + +add_library(gnuradio-osmosdr SHARED + osmosdr_ranges.cc + osmosdr_sink_c_impl.cc + osmosdr_source_c_impl.cc + rtl_source_c.cc +) + +target_link_libraries(gnuradio-osmosdr + ${Boost_LIBRARIES} + ${GRUEL_LIBRARIES} + ${GNURADIO_CORE_LIBRARIES} +# ${GNURADIO_AUDIO_LIBRARIES} + ${LIBRTLSDR_LIBRARIES} +) + +set_target_properties(gnuradio-osmosdr PROPERTIES DEFINE_SYMBOL "gnuradio_osmosdr_EXPORTS") + +######################################################################## +# Install built library files +######################################################################## +install(TARGETS gnuradio-osmosdr + LIBRARY DESTINATION lib${LIB_SUFFIX} # .so/.dylib file + ARCHIVE DESTINATION lib${LIB_SUFFIX} # .lib file + RUNTIME DESTINATION bin # .dll file +) + +######################################################################## +# Add subdirectories +######################################################################## +#add_subdirectory(fcd) +#add_subdirectory(osmosdr) +#add_subdirectory(rtl) +#add_subdirectory(uhd) diff --git a/lib/osmosdr_ranges.cc b/lib/osmosdr_ranges.cc new file mode 100644 index 0000000..86a8d16 --- /dev/null +++ b/lib/osmosdr_ranges.cc @@ -0,0 +1,163 @@ +// +// Copyright 2011-2011 Ettus Research LLC +// +// This program 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 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <osmosdr_ranges.h> +#include <stdexcept> +#include <boost/math/special_functions/round.hpp> +#include <boost/foreach.hpp> +#include <algorithm> +#include <sstream> + +using namespace osmosdr; + +/*********************************************************************** + * range_t implementation code + **********************************************************************/ +struct range_t::impl{ + impl(double start, double stop, double step): + start(start), stop(stop), step(step) + { + /* NOP */ + } + double start, stop, step; +}; + +range_t::range_t(double value): + _impl(OSMOSDR_PIMPL_MAKE(impl, (value, value, 0))) +{ + /* NOP */ +} + +range_t::range_t( + double start, double stop, double step +): + _impl(OSMOSDR_PIMPL_MAKE(impl, (start, stop, step))) +{ + if (stop < start){ + throw std::runtime_error("cannot make range where stop < start"); + } +} + +double range_t::start(void) const{ + return _impl->start; +} + +double range_t::stop(void) const{ + return _impl->stop; +} + +double range_t::step(void) const{ + return _impl->step; +} + +const std::string range_t::to_pp_string(void) const{ + std::stringstream ss; + ss << "(" << this->start(); + if (this->start() != this->stop()) ss << ", " << this->stop(); + if (this->step() != 0) ss << ", " << this->step(); + ss << ")"; + return ss.str(); +} + +/*********************************************************************** + * meta_range_t implementation code + **********************************************************************/ +void check_meta_range_monotonic(const meta_range_t &mr){ + if (mr.empty()){ + throw std::runtime_error("meta-range cannot be empty"); + } + for (size_t i = 1; i < mr.size(); i++){ + if (mr.at(i).start() < mr.at(i-1).stop()){ + throw std::runtime_error("meta-range is not monotonic"); + } + } +} + +meta_range_t::meta_range_t(void){ + /* NOP */ +} + +meta_range_t::meta_range_t( + double start, double stop, double step +): + std::vector<range_t > (1, range_t(start, stop, step)) +{ + /* NOP */ +} + +double meta_range_t::start(void) const{ + check_meta_range_monotonic(*this); + double min_start = this->front().start(); + BOOST_FOREACH(const range_t &r, (*this)){ + min_start = std::min(min_start, r.start()); + } + return min_start; +} + +double meta_range_t::stop(void) const{ + check_meta_range_monotonic(*this); + double max_stop = this->front().stop(); + BOOST_FOREACH(const range_t &r, (*this)){ + max_stop = std::max(max_stop, r.stop()); + } + return max_stop; +} + +double meta_range_t::step(void) const{ + check_meta_range_monotonic(*this); + std::vector<double> non_zero_steps; + range_t last = this->front(); + BOOST_FOREACH(const range_t &r, (*this)){ + //steps at each range + if (r.step() > 0) non_zero_steps.push_back(r.step()); + //and steps in-between ranges + double ibtw_step = r.start() - last.stop(); + if (ibtw_step > 0) non_zero_steps.push_back(ibtw_step); + //store ref to last + last = r; + } + if (non_zero_steps.empty()) return 0; //all zero steps, its zero... + return *std::min_element(non_zero_steps.begin(), non_zero_steps.end()); +} + +double meta_range_t::clip(double value, bool clip_step) const{ + check_meta_range_monotonic(*this); + double last_stop = this->front().stop(); + BOOST_FOREACH(const range_t &r, (*this)){ + //in-between ranges, clip to nearest + if (value < r.start()){ + return (std::abs(value - r.start()) < std::abs(value - last_stop))? + r.start() : last_stop; + } + //in this range, clip here + if (value <= r.stop()){ + if (not clip_step or r.step() == 0) return value; + return boost::math::round((value - r.start())/r.step())*r.step() + r.start(); + } + //continue on to the next range + last_stop = r.stop(); + } + return last_stop; +} + +const std::string meta_range_t::to_pp_string(void) const{ + std::stringstream ss; + BOOST_FOREACH(const range_t &r, (*this)){ + ss << r.to_pp_string() << std::endl; + } + return ss.str(); +} diff --git a/lib/osmosdr_sink_c_impl.cc b/lib/osmosdr_sink_c_impl.cc new file mode 100644 index 0000000..f5b2ec6 --- /dev/null +++ b/lib/osmosdr_sink_c_impl.cc @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net> + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* + * config.h is generated by configure. It contains the results + * of probing for features, options etc. It should be the first + * file included in your .cc file. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <osmosdr_sink_c_impl.h> +#include <gr_io_signature.h> + +/* + * Create a new instance of osmosdr_sink_c_impl and return + * a boost shared_ptr. This is effectively the public constructor. + */ +osmosdr_sink_c_sptr +osmosdr_make_sink_c (const std::string &args) +{ + return gnuradio::get_initial_sptr(new osmosdr_sink_c_impl (args)); +} + +/* + * Specify constraints on number of input and output streams. + * This info is used to construct the input and output signatures + * (2nd & 3rd args to gr_block's constructor). The input and + * output signatures are used by the runtime system to + * check that a valid number and type of inputs and outputs + * are connected to this block. In this case, we accept + * only 1 input and 1 output. + */ +static const int MIN_IN = 0; // mininum number of input streams +static const int MAX_IN = 0; // maximum number of input streams +static const int MIN_OUT = 1; // minimum number of output streams +static const int MAX_OUT = 1; // maximum number of output streams + +/* + * The private constructor + */ +osmosdr_sink_c_impl::osmosdr_sink_c_impl (const std::string &args) + : gr_hier_block2 ("osmosdr_sink_c_impl", + gr_make_io_signature (MIN_IN, MAX_IN, sizeof (gr_complex)), + gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (gr_complex))) +{ + //connect(_src, 0, self(), 0); +} diff --git a/lib/osmosdr_sink_c_impl.h b/lib/osmosdr_sink_c_impl.h new file mode 100644 index 0000000..44d66c9 --- /dev/null +++ b/lib/osmosdr_sink_c_impl.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net> + * + * 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_OSMOSDR_SINK_C_IMPL_H +#define INCLUDED_OSMOSDR_SINK_C_IMPL_H + +#include <osmosdr_api.h> +#include <osmosdr_sink_c.h> + +class OSMOSDR_API osmosdr_sink_c_impl : public osmosdr_sink_c +{ +public: + +private: + osmosdr_sink_c_impl (const std::string & args); // private constructor + + // The friend declaration allows osmosdr_make_sink_c to + // access the private constructor. + friend OSMOSDR_API osmosdr_sink_c_sptr osmosdr_make_sink_c (const std::string & args); +}; + +#endif /* INCLUDED_OSMOSDR_SINK_C_IMPL_H */ diff --git a/lib/osmosdr_source_c_impl.cc b/lib/osmosdr_source_c_impl.cc new file mode 100644 index 0000000..46734a8 --- /dev/null +++ b/lib/osmosdr_source_c_impl.cc @@ -0,0 +1,136 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net> + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* + * config.h is generated by configure. It contains the results + * of probing for features, options etc. It should be the first + * file included in your .cc file. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <osmosdr_source_c_impl.h> +#include <gr_io_signature.h> + +/* + * Create a new instance of osmosdr_source_c_impl and return + * a boost shared_ptr. This is effectively the public constructor. + */ +osmosdr_source_c_sptr +osmosdr_make_source_c (const std::string &args) +{ + return gnuradio::get_initial_sptr(new osmosdr_source_c_impl (args)); +} + +/* + * Specify constraints on number of input and output streams. + * This info is used to construct the input and output signatures + * (2nd & 3rd args to gr_block's constructor). The input and + * output signatures are used by the runtime system to + * check that a valid number and type of inputs and outputs + * are connected to this block. In this case, we accept + * only 1 input and 1 output. + */ +static const int MIN_IN = 0; // mininum number of input streams +static const int MAX_IN = 0; // maximum number of input streams +static const int MIN_OUT = 1; // minimum number of output streams +static const int MAX_OUT = 1; // maximum number of output streams + +/* + * The private constructor + */ +osmosdr_source_c_impl::osmosdr_source_c_impl (const std::string &args) + : gr_hier_block2 ("osmosdr_source_c_impl", + gr_make_io_signature (MIN_IN, MAX_IN, sizeof (gr_complex)), + gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (gr_complex))) +{ + _src = make_rtl_source_c( args ); + + connect(_src, 0, self(), 0); +} + +osmosdr::meta_range_t osmosdr_source_c_impl::get_samp_rates( void ) +{ + +} + +double osmosdr_source_c_impl::set_samp_rate( double rate ) +{ + return _src->set_sample_rate( rate ); +} + +double osmosdr_source_c_impl::get_samp_rate( void ) +{ + return _src->get_sample_rate(); +} + +osmosdr::freq_range_t osmosdr_source_c_impl::get_freq_range( size_t chan ) +{ + +} + +double osmosdr_source_c_impl::set_center_freq( double freq, size_t chan ) +{ + return _src->set_center_freq( freq ); +} + +double osmosdr_source_c_impl::get_center_freq( size_t chan ) +{ + +} + +double osmosdr_source_c_impl::set_freq_correction( double ppm, size_t chan ) +{ + +} + +double osmosdr_source_c_impl::get_freq_correction( size_t chan ) +{ + +} + +std::vector<std::string> osmosdr_source_c_impl::get_gain_names( size_t chan ) +{ + +} + +osmosdr::gain_range_t osmosdr_source_c_impl::get_gain_range( const std::string & name, size_t chan ) +{ + +} + +void osmosdr_source_c_impl::set_gain( double gain, size_t chan ) +{ + _src->set_gain( gain ); +} + +void osmosdr_source_c_impl::set_gain( double gain, const std::string & name, size_t chan ) +{ + +} + +double osmosdr_source_c_impl::get_gain( const std::string & name, size_t chan ) +{ + +} diff --git a/lib/osmosdr_source_c_impl.h b/lib/osmosdr_source_c_impl.h new file mode 100644 index 0000000..91bf953 --- /dev/null +++ b/lib/osmosdr_source_c_impl.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net> + * + * 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_OSMOSDR_SOURCE_C_IMPL_H +#define INCLUDED_OSMOSDR_SOURCE_C_IMPL_H + +#include <osmosdr_api.h> +#include <osmosdr_source_c.h> + +#include <rtl_source_c.h> + +class OSMOSDR_API osmosdr_source_c_impl : public osmosdr_source_c +{ +public: + osmosdr::meta_range_t get_samp_rates( void ); + double set_samp_rate( double rate ); + double get_samp_rate( void ); + + osmosdr::freq_range_t get_freq_range( size_t chan = 0 ); + double set_center_freq( double freq, size_t chan = 0 ); + double get_center_freq( size_t chan = 0 ); + double set_freq_correction( double ppm, size_t chan = 0 ); + double get_freq_correction( size_t chan = 0 ); + + std::vector<std::string> get_gain_names( size_t chan = 0 ); + osmosdr::gain_range_t get_gain_range( const std::string & name = "", size_t chan = 0 ); + void set_gain( double gain, size_t chan = 0 ); + void set_gain( double gain, const std::string & name = "", size_t chan = 0 ); + double get_gain( const std::string & name = "", size_t chan = 0 ); + +private: + osmosdr_source_c_impl (const std::string & args); // private constructor + + // The friend declaration allows osmosdr_make_source_c to + // access the private constructor. + friend OSMOSDR_API osmosdr_source_c_sptr osmosdr_make_source_c (const std::string & args); + + rtl_source_c_sptr _src; +}; + +#endif /* INCLUDED_OSMOSDR_SOURCE_C_IMPL_H */ diff --git a/lib/rtl_source_c.cc b/lib/rtl_source_c.cc new file mode 100644 index 0000000..82001f9 --- /dev/null +++ b/lib/rtl_source_c.cc @@ -0,0 +1,229 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net> + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* + * config.h is generated by configure. It contains the results + * of probing for features, options etc. It should be the first + * file included in your .cc file. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtl_source_c.h> +#include <gr_io_signature.h> + +#include <stdexcept> +#include <iostream> +#include <stdio.h> + +#include <rtl-sdr.h> + +/* + * Create a new instance of rtl_source_c and return + * a boost shared_ptr. This is effectively the public constructor. + */ +rtl_source_c_sptr +make_rtl_source_c (const std::string &args) +{ + return gnuradio::get_initial_sptr(new rtl_source_c (args)); +} + +/* + * Specify constraints on number of input and output streams. + * This info is used to construct the input and output signatures + * (2nd & 3rd args to gr_block's constructor). The input and + * output signatures are used by the runtime system to + * check that a valid number and type of inputs and outputs + * are connected to this block. In this case, we accept + * only 1 input and 1 output. + */ +static const int MIN_IN = 0; // mininum number of input streams +static const int MAX_IN = 0; // maximum number of input streams +static const int MIN_OUT = 1; // minimum number of output streams +static const int MAX_OUT = 1; // maximum number of output streams + +/* + * The private constructor + */ +rtl_source_c::rtl_source_c (const std::string &args) + : gr_sync_block ("rtl_source_c", + gr_make_io_signature (MIN_IN, MAX_IN, sizeof (gr_complex)), + gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (gr_complex))) +{ + int ret; + int dev_index = 0; + + _buf = boost::circular_buffer<unsigned char>(1024*1024); + + // create a lookup table for gr_complex values + for (unsigned int i = 0; i <= 0xffff; i++) + { + _lut.push_back( gr_complex( ((i >> 8) - 127) * 0.00787, + ((i & 0xff) - 127) * 0.00787 ) ); + } + + std::cout << "Opening " << rtlsdr_get_device_name(dev_index) << std::endl; + + _dev = NULL; + ret = rtlsdr_open(&_dev, dev_index); + if (ret < 0) + throw std::runtime_error("failed to open rtlsdr device."); + + ret = rtlsdr_reset_buffer(_dev); + if (ret < 0) + throw std::runtime_error("failed to reset usb buffers."); + + rtlsdr_set_sample_rate( _dev, 2048000 ); + + _has_i_sample = false; + + _thread = gruel::thread(_rtlsdr_wait, this); +} + +/* + * Our virtual destructor. + */ +rtl_source_c::~rtl_source_c () +{ + if (_dev) { + rtlsdr_cancel_async( _dev ); + _thread.join(); + rtlsdr_close( _dev ); + _dev = NULL; + } +} + +void rtl_source_c::_rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx) +{ + rtl_source_c *obj = (rtl_source_c *)ctx; + obj->rtlsdr_callback(buf, len); +} + +void rtl_source_c::rtlsdr_callback(unsigned char *buf, uint32_t len) +{ + boost::mutex::scoped_lock lock( _buf_mutex ); + + for (int i = 0; i < len; i++) { + if (!_buf.full()) { + _buf.push_back(buf[i]); + _buf_cond.notify_one(); + } else { + printf("O"); fflush(stdout); + break; + } + } +} + +void rtl_source_c::_rtlsdr_wait(rtl_source_c *obj) +{ + obj->rtlsdr_wait(); +} + +void rtl_source_c::rtlsdr_wait() +{ + int ret = rtlsdr_wait_async(_dev, _rtlsdr_callback, (void *)this); + if (-10 == ret) + ret = rtlsdr_wait_async(_dev, _rtlsdr_callback, (void *)this); + + std::cout << "rtlsdr_wait() finished due to " << ret << std::endl; +} + +int rtl_source_c::work( int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items ) +{ + gr_complex *out = (gr_complex *) output_items[0]; + + unsigned short index = 0; + + int items_left = noutput_items; + while ( items_left ) + { + { + boost::mutex::scoped_lock lock( _buf_mutex ); + + while( _buf.empty() ) { + _buf_cond.wait( lock ); + } + } + + if (!_has_i_sample) { + index = _buf.front() << 8; + _buf.pop_front(); + _has_i_sample = true; + } else { + index |= _buf.front(); + _buf.pop_front(); + _has_i_sample = false; + } + + if (_has_i_sample) + continue; + + // convert samples to gr_complex type by using the lookup table + *out++ = _lut[index]; + + items_left--; + } + + return noutput_items; +} + +double rtl_source_c::set_center_freq(double freq) +{ + if (_dev) { + rtlsdr_set_center_freq( _dev, (unsigned int)freq ); + return (double)rtlsdr_get_center_freq( _dev ); + } + + return 0; +} + +double rtl_source_c::set_sample_rate( double rate ) +{ + if (_dev) { + rtlsdr_set_sample_rate( _dev, (unsigned int)rate ); + return (double)rtlsdr_get_sample_rate( _dev ); + } + + return 0; +} + +double rtl_source_c::get_sample_rate() +{ + if (_dev) + return (double) rtlsdr_get_sample_rate( _dev ); + + return 0; +} + +double rtl_source_c::set_gain( double gain ) +{ + if (_dev) { + rtlsdr_set_tuner_gain( _dev, (unsigned int)gain ); + return (double)rtlsdr_get_tuner_gain( _dev ); + } + + return 0; +} diff --git a/lib/rtl_source_c.h b/lib/rtl_source_c.h new file mode 100644 index 0000000..bd3dedd --- /dev/null +++ b/lib/rtl_source_c.h @@ -0,0 +1,104 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net> + * + * 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_RTLSDR_SOURCE_C_H +#define INCLUDED_RTLSDR_SOURCE_C_H + +#include <osmosdr_api.h> +#include <gr_sync_block.h> +#include <gruel/thread.h> +#include <boost/circular_buffer.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/condition_variable.hpp> + +class rtl_source_c; +typedef struct rtlsdr_dev rtlsdr_dev_t; + +/* + * We use boost::shared_ptr's instead of raw pointers for all access + * to gr_blocks (and many other data structures). The shared_ptr gets + * us transparent reference counting, which greatly simplifies storage + * management issues. This is especially helpful in our hybrid + * C++ / Python system. + * + * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm + * + * As a convention, the _sptr suffix indicates a boost::shared_ptr + */ +typedef boost::shared_ptr<rtl_source_c> rtl_source_c_sptr; + +/*! + * \brief Return a shared_ptr to a new instance of rtl_source_c. + * + * To avoid accidental use of raw pointers, rtl_source_c's + * constructor is private. make_rtl_source_c is the public + * interface for creating new instances. + */ +OSMOSDR_API rtl_source_c_sptr make_rtl_source_c (const std::string & args = ""); + +/*! + * \brief Provides a stream of complex samples. + * \ingroup block + * + */ +class OSMOSDR_API rtl_source_c : public gr_sync_block +{ +private: + // The friend declaration allows make_rtl_source_c to + // access the private constructor. + + friend OSMOSDR_API rtl_source_c_sptr make_rtl_source_c (const std::string & args); + + /*! + * \brief Provides a stream of complex samples. + */ + rtl_source_c (const std::string & args); // private constructor + +public: + ~rtl_source_c (); // public destructor + + int work( int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items ); + + double set_center_freq( double freq ); + double set_sample_rate( double rate ); + double get_sample_rate(); + double set_gain( double gain ); + +private: + static void _rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx); + void rtlsdr_callback(unsigned char *buf, uint32_t len); + static void _rtlsdr_wait(rtl_source_c *obj); + void rtlsdr_wait(); + + std::vector<gr_complex> _lut; + + rtlsdr_dev_t *_dev; + gruel::thread _thread; + boost::circular_buffer<unsigned char> _buf; + boost::mutex _buf_mutex; + boost::condition_variable _buf_cond; + bool _has_i_sample; +}; + +#endif /* INCLUDED_RTLSDR_SOURCE_C_H */ |