From 619d7a5a8b7a442f565bf92fa534738f9ac40e97 Mon Sep 17 00:00:00 2001 From: Dimitri Stolnikov Date: Wed, 11 Apr 2012 23:37:02 +0200 Subject: [PATCH] cleanup interface & documentation --- include/osmosdr/osmosdr_sink_c.h | 2 +- include/osmosdr/osmosdr_source_c.h | 181 +++++++++++++-------------- lib/osmosdr_source_c_impl.cc | 64 +++++++--- lib/osmosdr_source_c_impl.h | 26 ++-- lib/osmosdr_src_iface.h | 183 +++++++++++++++++++++++++++ lib/rtl_source_c.cc | 194 +++++++++++++++++++++++------ lib/rtl_source_c.h | 31 ++++- 7 files changed, 523 insertions(+), 158 deletions(-) create mode 100644 lib/osmosdr_src_iface.h diff --git a/include/osmosdr/osmosdr_sink_c.h b/include/osmosdr/osmosdr_sink_c.h index 41023ab..b3a976c 100644 --- a/include/osmosdr/osmosdr_sink_c.h +++ b/include/osmosdr/osmosdr_sink_c.h @@ -48,7 +48,7 @@ typedef boost::shared_ptr osmosdr_sink_c_sptr; * constructor is private. osmosdr_make_sink_c is the public * interface for creating new instances. */ -OSMOSDR_API osmosdr_sink_c_sptr osmosdr_make_sink_c (const std::string & args = ""); +OSMOSDR_API osmosdr_sink_c_sptr osmosdr_make_sink_c ( const std::string & args = "" ); /*! * \brief Takes a stream of complex samples. diff --git a/include/osmosdr/osmosdr_source_c.h b/include/osmosdr/osmosdr_source_c.h index e4bb6ca..d55bb21 100644 --- a/include/osmosdr/osmosdr_source_c.h +++ b/include/osmosdr/osmosdr_source_c.h @@ -49,165 +49,162 @@ typedef boost::shared_ptr osmosdr_source_c_sptr; * constructor is private. osmosdr_make_source_c is the public * interface for creating new instances. */ -OSMOSDR_API osmosdr_source_c_sptr osmosdr_make_source_c (const std::string & args = ""); +OSMOSDR_API osmosdr_source_c_sptr osmosdr_make_source_c ( const std::string & args = "" ); /*! * \brief Provides a stream of complex samples. * \ingroup block * - * \sa osmosdr_sink_c for a version that subclasses gr_hier_block2. + * This uses the preferred technique: subclassing gr_hier_block2. */ class OSMOSDR_API osmosdr_source_c : virtual public gr_hier_block2 { public: /*! - * Get the possible sample rates for the OsmoSDR device. - * \return a range of rates in Sps + * Get the number of channels the underlying radio hardware offers. + * \return the number of available channels */ - virtual osmosdr::meta_range_t get_samp_rates( void ) = 0; + virtual size_t get_num_channels( void ) = 0; /*! - * Set the sample rate for the OsmoSDR device. + * Get the possible sample rates for the underlying radio hardware. + * \return a range of rates in Sps + */ + virtual osmosdr::meta_range_t get_sample_rates( void ) = 0; + + /*! + * Set the sample rate for the underlying radio hardware. * This also will select the appropriate IF bandpass, if applicable. * \param rate a new rate in Sps */ - virtual double set_samp_rate( double rate ) = 0; + virtual double set_sample_rate( double rate ) = 0; /*! - * Get the sample rate for the OsmoSDR device. + * Get the sample rate for the underlying radio hardware. * This is the actual sample rate and may differ from the rate set. * \return the actual rate in Sps */ - virtual double get_samp_rate( void ) = 0; + virtual double get_sample_rate( void ) = 0; /*! - * Get the tunable frequency range. + * Get the tunable frequency range for the underlying radio hardware. + * \param chan the channel index 0 to N-1 * \return the frequency range in Hz */ virtual osmosdr::freq_range_t get_freq_range( size_t chan = 0 ) = 0; /*! - * Tune the OsmoSDR device to the desired center frequency. + * Tune the underlying radio hardware to the desired center frequency. * This also will select the appropriate RF bandpass. * \param freq the desired frequency in Hz - * \return a tune result with the actual frequencies + * \param chan the channel index 0 to N-1 + * \return the actual frequency in Hz */ virtual double set_center_freq( double freq, size_t chan = 0 ) = 0; /*! - * Get the center frequency. + * Get the center frequency the underlying radio hardware is tuned to. + * This is the actual frequency and may differ from the frequency set. + * \param chan the channel index 0 to N-1 * \return the frequency in Hz */ virtual double get_center_freq( size_t chan = 0 ) = 0; /*! * Set the frequency correction value in parts per million. + * \param ppm the desired correction value in parts per million + * \param chan the channel index 0 to N-1 * \return correction value in parts per million */ - virtual double set_freq_correction( double ppm, size_t chan = 0 ) = 0; + virtual double set_freq_corr( double ppm, size_t chan = 0 ) = 0; /*! * Get the frequency correction value. + * \param chan the channel index 0 to N-1 * \return correction value in parts per million */ - virtual double get_freq_correction( size_t chan = 0 ) = 0; + virtual double get_freq_corr( size_t chan = 0 ) = 0; /*! - * Get the actual OsmoSDR gain setting of named stage. - * \return the actual gain in dB + * Get the gain stage names of the underlying radio hardware. + * \param chan the channel index 0 to N-1 + * \return a vector of strings containing the names of gain stages */ virtual std::vector get_gain_names( size_t chan = 0 ) = 0; /*! - * Get the settable gain range. - * \param name the name of the gain stage + * Get the settable overall gain range for the underlying radio hardware. + * \param chan the channel index 0 to N-1 * \return the gain range in dB */ - virtual osmosdr::gain_range_t get_gain_range( const std::string & name = "", size_t chan = 0 ) = 0; + virtual osmosdr::gain_range_t get_gain_range( size_t chan = 0 ) = 0; /*! - * Set the gain for the OsmoSDR. - * \param gain the gain in dB - */ - virtual void set_gain( double gain, size_t chan = 0 ) = 0; - - /*! - * Set the named gain on the OsmoSDR. - * \param gain the gain in dB + * Get the settable gain range for a specific gain stage. * \param name the name of the gain stage + * \param chan the channel index 0 to N-1 + * \return the gain range in dB */ - virtual void set_gain( double gain, const std::string & name = "", size_t chan = 0 ) = 0; + virtual osmosdr::gain_range_t get_gain_range( const std::string & name, + size_t chan = 0 ) = 0; /*! - * Get the actual OsmoSDR gain setting of a named stage. - * \param name the name of the gain stage + * Set the gain for the underlying radio hardware. + * This function will automatically distribute the desired gain value over + * available gain stages in an appropriate way and return the actual value. + * \param gain the gain in dB + * \param chan the channel index 0 to N-1 * \return the actual gain in dB */ - virtual double get_gain( const std::string & name = "", size_t chan = 0 ) = 0; + virtual double set_gain( double gain, size_t chan = 0 ) = 0; -#if 0 + /*! + * Set the named gain on the underlying radio hardware. + * \param gain the gain in dB + * \param name the name of the gain stage + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual double set_gain( double gain, + const std::string & name, + size_t chan = 0 ) = 0; + /*! + * Get the actual gain setting of the underlying radio hardware. + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual double get_gain( size_t chan = 0 ) = 0; + + /*! + * Get the actual gain setting of a named stage. + * \param name the name of the gain stage + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual double get_gain( const std::string & name, size_t chan = 0 ) = 0; + + /*! + * Get the available antennas of the underlying radio hardware. + * \param chan the channel index 0 to N-1 + * \return a vector of strings containing the names of available antennas + */ virtual std::vector< std::string > get_antennas( size_t chan = 0 ) = 0; - virtual std::string set_antenna( const std::string & antenna, size_t chan = 0 ) = 0; + + /*! + * Select the active antenna of the underlying radio hardware. + * \param chan the channel index 0 to N-1 + * \return the actual antenna's name + */ + virtual std::string set_antenna( const std::string & antenna, + size_t chan = 0 ) = 0; + + /*! + * Get the actual underlying radio hardware antenna setting. + * \param chan the channel index 0 to N-1 + * \return antenna the actual antenna's name + */ virtual std::string get_antenna( size_t chan = 0 ) = 0; - - /*! - * Enable/disable the automatic DC offset correction. - * The automatic correction subtracts out the long-run average. - * - * When disabled, the averaging option operation is halted. - * Once halted, the average value will be held constant - * until the user re-enables the automatic correction - * or overrides the value by manually setting the offset. - * - * \param enb true to enable automatic DC offset correction - */ - virtual void set_dc_offset(const bool enb) = 0; - - /*! - * Set a constant DC offset value. - * The value is complex to control both I and Q. - * Only set this when automatic correction is disabled. - * \param offset the dc offset (1.0 is full-scale) - */ - virtual void set_dc_offset(const std::complex &offset) = 0; - - /*! - * Set the RX frontend IQ imbalance correction. - * Use this to adjust the magnitude and phase of I and Q. - * - * \param correction the complex correction value - */ - virtual void set_iq_balance(const std::complex &correction) = 0; - - /*! - * Get the master clock rate. - * \return the clock rate in Hz - */ - virtual double get_clock_rate() = 0; - - /*! - * Set the master clock rate. - * \param rate the new rate in Hz - */ - virtual void set_clock_rate(double rate) = 0; - - /*! - * Get automatic gain control status - * \return the clock rate in Hz - */ - virtual bool get_agc() = 0; - - /*! - * Enable/disable the automatic gain control. - * \param enb true to enable automatic gain control - * \param attack attack time of the AGC circuit - * \param decay decay time of the AGC circuit - */ - virtual void set_agc(bool enb, double attack, double decay) = 0; - - /*! TODO: add more */ -#endif }; #endif /* INCLUDED_OSMOSDR_SOURCE_C_H */ diff --git a/lib/osmosdr_source_c_impl.cc b/lib/osmosdr_source_c_impl.cc index 46734a8..b48bdc3 100644 --- a/lib/osmosdr_source_c_impl.cc +++ b/lib/osmosdr_source_c_impl.cc @@ -70,67 +70,97 @@ osmosdr_source_c_impl::osmosdr_source_c_impl (const std::string &args) connect(_src, 0, self(), 0); } -osmosdr::meta_range_t osmosdr_source_c_impl::get_samp_rates( void ) +size_t osmosdr_source_c_impl::get_num_channels() { - + return _src->get_num_channels(); } -double osmosdr_source_c_impl::set_samp_rate( double rate ) +osmosdr::meta_range_t osmosdr_source_c_impl::get_sample_rates() { - return _src->set_sample_rate( rate ); + return _src->get_sample_rates(); } -double osmosdr_source_c_impl::get_samp_rate( void ) +double osmosdr_source_c_impl::set_sample_rate(double rate) +{ + return _src->set_sample_rate(rate); +} + +double osmosdr_source_c_impl::get_sample_rate() { return _src->get_sample_rate(); } osmosdr::freq_range_t osmosdr_source_c_impl::get_freq_range( size_t chan ) { - + return _src->get_freq_range( chan ); } double osmosdr_source_c_impl::set_center_freq( double freq, size_t chan ) { - return _src->set_center_freq( freq ); + return _src->set_center_freq( freq, chan ); } double osmosdr_source_c_impl::get_center_freq( size_t chan ) { - + return _src->get_center_freq( chan ); } -double osmosdr_source_c_impl::set_freq_correction( double ppm, size_t chan ) +double osmosdr_source_c_impl::set_freq_corr( double ppm, size_t chan ) { - + return _src->set_freq_corr( ppm, chan ); } -double osmosdr_source_c_impl::get_freq_correction( size_t chan ) +double osmosdr_source_c_impl::get_freq_corr( size_t chan ) { - + return _src->get_freq_corr( chan ); } std::vector osmosdr_source_c_impl::get_gain_names( size_t chan ) { + return _src->get_gain_names( chan ); +} +osmosdr::gain_range_t osmosdr_source_c_impl::get_gain_range( size_t chan ) +{ + return _src->get_gain_range( chan ); } osmosdr::gain_range_t osmosdr_source_c_impl::get_gain_range( const std::string & name, size_t chan ) { - + return _src->get_gain_range( name, chan ); } -void osmosdr_source_c_impl::set_gain( double gain, size_t chan ) +double osmosdr_source_c_impl::set_gain( double gain, size_t chan ) { - _src->set_gain( gain ); + return _src->set_gain( gain, chan ); } -void osmosdr_source_c_impl::set_gain( double gain, const std::string & name, size_t chan ) +double osmosdr_source_c_impl::set_gain( double gain, const std::string & name, size_t chan) { + return _src->set_gain( gain, name, chan ); +} +double osmosdr_source_c_impl::get_gain( size_t chan ) +{ + return _src->get_gain( chan ); } double osmosdr_source_c_impl::get_gain( const std::string & name, size_t chan ) { - + return _src->get_gain( name, chan ); +} + +std::vector< std::string > osmosdr_source_c_impl::get_antennas( size_t chan ) +{ + return _src->get_antennas( chan ); +} + +std::string osmosdr_source_c_impl::set_antenna( const std::string & antenna, size_t chan ) +{ + return _src->set_antenna( antenna, chan ); +} + +std::string osmosdr_source_c_impl::get_antenna( size_t chan ) +{ + return _src->get_antenna( chan ); } diff --git a/lib/osmosdr_source_c_impl.h b/lib/osmosdr_source_c_impl.h index 91bf953..63d6ba7 100644 --- a/lib/osmosdr_source_c_impl.h +++ b/lib/osmosdr_source_c_impl.h @@ -31,21 +31,29 @@ 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 ); + size_t get_num_channels( void ); + + osmosdr::meta_range_t get_sample_rates( void ); + double set_sample_rate( double rate ); + double get_sample_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 ); + double set_freq_corr( double ppm, size_t chan = 0 ); + double get_freq_corr( size_t chan = 0 ); std::vector 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 ); + osmosdr::gain_range_t get_gain_range( size_t chan = 0 ); + osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 ); + double set_gain( double gain, size_t chan = 0 ); + double set_gain( double gain, const std::string & name, size_t chan = 0 ); + double get_gain( size_t chan = 0 ); + double get_gain( const std::string & name, size_t chan = 0 ); + + std::vector< std::string > get_antennas( size_t chan = 0 ); + std::string set_antenna( const std::string & antenna, size_t chan = 0 ); + std::string get_antenna( size_t chan = 0 ); private: osmosdr_source_c_impl (const std::string & args); // private constructor diff --git a/lib/osmosdr_src_iface.h b/lib/osmosdr_src_iface.h new file mode 100644 index 0000000..28cb87b --- /dev/null +++ b/lib/osmosdr_src_iface.h @@ -0,0 +1,183 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * Copyright 2012 Dimitri Stolnikov + * + * 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 OSMOSDR_SRC_IFACE_H +#define OSMOSDR_SRC_IFACE_H + +#include + +/*! + * TODO: document + * + */ +class OSMOSDR_API osmosdr_src_iface +{ +public: + /*! + * Get the number of channels the underlying radio hardware offers. + * \return the number of available channels + */ + virtual size_t get_num_channels( void ) = 0; + + /*! + * Get the possible sample rates for the underlying radio hardware. + * \return a range of rates in Sps + */ + virtual osmosdr::meta_range_t get_sample_rates( void ) = 0; + + /*! + * Set the sample rate for the underlying radio hardware. + * This also will select the appropriate IF bandpass, if applicable. + * \param rate a new rate in Sps + */ + virtual double set_sample_rate( double rate ) = 0; + + /*! + * Get the sample rate for the underlying radio hardware. + * This is the actual sample rate and may differ from the rate set. + * \return the actual rate in Sps + */ + virtual double get_sample_rate( void ) = 0; + + /*! + * Get the tunable frequency range for the underlying radio hardware. + * \param chan the channel index 0 to N-1 + * \return the frequency range in Hz + */ + virtual osmosdr::freq_range_t get_freq_range( size_t chan = 0 ) = 0; + + /*! + * Tune the underlying radio hardware to the desired center frequency. + * This also will select the appropriate RF bandpass. + * \param freq the desired frequency in Hz + * \param chan the channel index 0 to N-1 + * \return the actual frequency in Hz + */ + virtual double set_center_freq( double freq, size_t chan = 0 ) = 0; + + /*! + * Get the center frequency the underlying radio hardware is tuned to. + * This is the actual frequency and may differ from the frequency set. + * \param chan the channel index 0 to N-1 + * \return the frequency in Hz + */ + virtual double get_center_freq( size_t chan = 0 ) = 0; + + /*! + * Set the frequency correction value in parts per million. + * \param ppm the desired correction value in parts per million + * \param chan the channel index 0 to N-1 + * \return correction value in parts per million + */ + virtual double set_freq_corr( double ppm, size_t chan = 0 ) = 0; + + /*! + * Get the frequency correction value. + * \param chan the channel index 0 to N-1 + * \return correction value in parts per million + */ + virtual double get_freq_corr( size_t chan = 0 ) = 0; + + /*! + * Get the gain stage names of the underlying radio hardware. + * \param chan the channel index 0 to N-1 + * \return a vector of strings containing the names of gain stages + */ + virtual std::vector get_gain_names( size_t chan = 0 ) = 0; + + /*! + * Get the settable overall gain range for the underlying radio hardware. + * \param chan the channel index 0 to N-1 + * \return the gain range in dB + */ + virtual osmosdr::gain_range_t get_gain_range( size_t chan = 0 ) = 0; + + /*! + * Get the settable gain range for a specific gain stage. + * \param name the name of the gain stage + * \param chan the channel index 0 to N-1 + * \return the gain range in dB + */ + virtual osmosdr::gain_range_t get_gain_range( const std::string & name, + size_t chan = 0 ) = 0; + + /*! + * Set the gain for the underlying radio hardware. + * This function will automatically distribute the desired gain value over + * available gain stages in an appropriate way and return the actual value. + * \param gain the gain in dB + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual double set_gain( double gain, size_t chan = 0 ) = 0; + + /*! + * Set the named gain on the underlying radio hardware. + * \param gain the gain in dB + * \param name the name of the gain stage + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual double set_gain( double gain, + const std::string & name, + size_t chan = 0 ) = 0; + + /*! + * Get the actual gain setting of the underlying radio hardware. + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual double get_gain( size_t chan = 0 ) = 0; + + /*! + * Get the actual gain setting of a named stage. + * \param name the name of the gain stage + * \param chan the channel index 0 to N-1 + * \return the actual gain in dB + */ + virtual double get_gain( const std::string & name, size_t chan = 0 ) = 0; + + /*! + * Get the available antennas of the underlying radio hardware. + * \param chan the channel index 0 to N-1 + * \return a vector of strings containing the names of available antennas + */ + virtual std::vector< std::string > get_antennas( size_t chan = 0 ) = 0; + + /*! + * Select the active antenna of the underlying radio hardware. + * \param chan the channel index 0 to N-1 + * \return the actual antenna's name + */ + virtual std::string set_antenna( const std::string & antenna, + size_t chan = 0 ) = 0; + + /*! + * Get the actual underlying radio hardware antenna setting. + * \param chan the channel index 0 to N-1 + * \return antenna the actual antenna's name + */ + virtual std::string get_antenna( size_t chan = 0 ) = 0; +}; + +#endif // OSMOSDR_SRC_IFACE_H diff --git a/lib/rtl_source_c.cc b/lib/rtl_source_c.cc index 408dea3..6b08d75 100644 --- a/lib/rtl_source_c.cc +++ b/lib/rtl_source_c.cc @@ -33,12 +33,16 @@ #include #include +#include + #include #include #include #include +using namespace boost::assign; + /* * Create a new instance of rtl_source_c and return * a boost shared_ptr. This is effectively the public constructor. @@ -88,18 +92,24 @@ rtl_source_c::rtl_source_c (const std::string &args) #endif } - std::cout << "Opening " << rtlsdr_get_device_name(dev_index) << std::endl; + std::cerr << "Using device #" << dev_index << " " + << "(" << rtlsdr_get_device_name(dev_index) << ")" + << std::endl; _dev = NULL; - ret = rtlsdr_open(&_dev, dev_index); + ret = rtlsdr_open( &_dev, dev_index ); if (ret < 0) - throw std::runtime_error("failed to open rtlsdr device."); + throw std::runtime_error("Failed to open rtlsdr device."); - ret = rtlsdr_reset_buffer(_dev); + ret = rtlsdr_set_sample_rate( _dev, 1024000 ); if (ret < 0) - throw std::runtime_error("failed to reset usb buffers."); + throw std::runtime_error("Failed to set default samplerate."); -// rtlsdr_set_sample_rate( _dev, 2048000 ); + ret = rtlsdr_reset_buffer( _dev ); + if (ret < 0) + throw std::runtime_error("Failed to reset usb buffers."); + + _running = true; _thread = gruel::thread(_rtlsdr_wait, this); } @@ -127,21 +137,22 @@ void rtl_source_c::rtlsdr_callback(unsigned char *buf, uint32_t len) { unsigned short * sbuf = (unsigned short *)buf; - if (len % 2 != 0) { - printf("len: %d\n", len); fflush(stdout); - } - boost::mutex::scoped_lock lock( _buf_mutex ); + if (len % 2 != 0) { + printf("!!! len: %d\n", len); fflush(stdout); + } + for (int i = 0; i < len/2; i++) { if (!_buf.full()) { - _buf.push_back(sbuf[i]); - _buf_cond.notify_one(); + _buf.push_back( sbuf[i] ); } else { printf("O"); fflush(stdout); break; } } + + _buf_cond.notify_one(); } void rtl_source_c::_rtlsdr_wait(rtl_source_c *obj) @@ -151,11 +162,12 @@ void rtl_source_c::_rtlsdr_wait(rtl_source_c *obj) 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); + int ret = rtlsdr_read_async( _dev, _rtlsdr_callback, (void *)this, 0, 0 ); - std::cout << "rtlsdr_wait() finished due to " << ret << std::endl; + _running = false; + + if ( ret != 0 ) + std::cerr << "rtlsdr_read_async returned with " << ret << std::endl; } int rtl_source_c::work( int noutput_items, @@ -164,6 +176,9 @@ int rtl_source_c::work( int noutput_items, { gr_complex *out = (gr_complex *)output_items[0]; + if (!_running) + return WORK_DONE; + int items_left = noutput_items; while ( items_left ) { @@ -177,53 +192,162 @@ int rtl_source_c::work( int noutput_items, // convert samples to gr_complex type by using the lookup table *out++ = _lut[ _buf.front() ]; + items_left--; { boost::mutex::scoped_lock lock( _buf_mutex ); _buf.pop_front(); } - - items_left--; } return noutput_items; } -double rtl_source_c::set_center_freq(double freq) +size_t rtl_source_c::get_num_channels() { - if (_dev) { - rtlsdr_set_center_freq( _dev, (unsigned int)freq ); - return (double)rtlsdr_get_center_freq( _dev ); - } - - return 0; + return 1; } -double rtl_source_c::set_sample_rate( double rate ) +osmosdr::meta_range_t rtl_source_c::get_sample_rates() +{ + osmosdr::meta_range_t range; + + range += osmosdr::range_t( 1024000 ); + range += osmosdr::range_t( 2048000 ); + range += osmosdr::range_t( 3200000 ); + + // TODO: read from the librtlsdr as soon as the api is available + + return range; +} + +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 ); + rtlsdr_set_sample_rate( _dev, (uint32_t)rate ); } - return 0; + return get_sample_rate(); } double rtl_source_c::get_sample_rate() { if (_dev) - return (double) rtlsdr_get_sample_rate( _dev ); + return (double)rtlsdr_get_sample_rate( _dev ); return 0; } -double rtl_source_c::set_gain( double gain ) +osmosdr::freq_range_t rtl_source_c::get_freq_range( size_t chan ) { - if (_dev) { - rtlsdr_set_tuner_gain( _dev, (unsigned int)gain ); - return (double)rtlsdr_get_tuner_gain( _dev ); - } + osmosdr::freq_range_t range; + + range += osmosdr::range_t( 50e6, 2.2e9, 100 ); + + // TODO: read from the librtlsdr as soon as the api is available + + return range; +} + +double rtl_source_c::set_center_freq( double freq, size_t chan ) +{ + if (_dev) + rtlsdr_set_center_freq( _dev, (uint32_t)freq ); + + return get_center_freq( chan ); +} + +double rtl_source_c::get_center_freq( size_t chan ) +{ + if (_dev) + return (double)rtlsdr_get_center_freq( _dev ); return 0; } + +double rtl_source_c::set_freq_corr( double ppm, size_t chan ) +{ + if ( _dev ) + rtlsdr_set_freq_correction( _dev, (int)ppm ); + + return get_freq_corr( chan ); +} + +double rtl_source_c::get_freq_corr( size_t chan ) +{ + if ( _dev ) + return (double)rtlsdr_get_freq_correction( _dev ); + + return 0; +} + +std::vector rtl_source_c::get_gain_names( size_t chan ) +{ + std::vector< std::string > antennas; + + antennas += "LNA"; + + return antennas; +} + +osmosdr::gain_range_t rtl_source_c::get_gain_range( size_t chan ) +{ + osmosdr::gain_range_t range; + + range += osmosdr::range_t( -5, 30, 2.5 ); + + // TODO: read from the librtlsdr as soon as the api is available + + return range; +} + +osmosdr::gain_range_t rtl_source_c::get_gain_range( const std::string & name, size_t chan ) +{ + return get_gain_range( chan ); +} + +double rtl_source_c::set_gain( double gain, size_t chan ) +{ + if (_dev) + rtlsdr_set_tuner_gain( _dev, gain ); + + return get_gain( chan ); +} + +double rtl_source_c::set_gain( double gain, const std::string & name, size_t chan) +{ + return set_gain( gain, chan ); +} + +double rtl_source_c::get_gain( size_t chan ) +{ + if ( _dev ) + return (double)rtlsdr_get_tuner_gain( _dev ); + + return 0; +} + +double rtl_source_c::get_gain( const std::string & name, size_t chan ) +{ + return get_gain( chan ); +} + +std::vector< std::string > rtl_source_c::get_antennas( size_t chan ) +{ + std::vector< std::string > antennas; + + antennas += get_antenna( chan ); + + return antennas; +} + +std::string rtl_source_c::set_antenna( const std::string & antenna, size_t chan ) +{ + return get_antenna( chan ); +} + +std::string rtl_source_c::get_antenna( size_t chan ) +{ + return "ANT"; +} diff --git a/lib/rtl_source_c.h b/lib/rtl_source_c.h index 8e6bbe7..1b85f61 100644 --- a/lib/rtl_source_c.h +++ b/lib/rtl_source_c.h @@ -30,6 +30,8 @@ #include #include +#include "osmosdr_src_iface.h" + class rtl_source_c; typedef struct rtlsdr_dev rtlsdr_dev_t; @@ -60,7 +62,8 @@ OSMOSDR_API rtl_source_c_sptr make_rtl_source_c (const std::string & args = ""); * \ingroup block * */ -class OSMOSDR_API rtl_source_c : public gr_sync_block +class OSMOSDR_API rtl_source_c : public gr_sync_block, + public osmosdr_src_iface { private: // The friend declaration allows make_rtl_source_c to @@ -80,10 +83,29 @@ public: gr_vector_const_void_star &input_items, gr_vector_void_star &output_items ); - double set_center_freq( double freq ); + size_t get_num_channels( void ); + + osmosdr::meta_range_t get_sample_rates( void ); double set_sample_rate( double rate ); - double get_sample_rate(); - double set_gain( double gain ); + double get_sample_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_corr( double ppm, size_t chan = 0 ); + double get_freq_corr( size_t chan = 0 ); + + std::vector get_gain_names( size_t chan = 0 ); + osmosdr::gain_range_t get_gain_range( size_t chan = 0 ); + osmosdr::gain_range_t get_gain_range( const std::string & name, size_t chan = 0 ); + double set_gain( double gain, size_t chan = 0 ); + double set_gain( double gain, const std::string & name, size_t chan = 0 ); + double get_gain( size_t chan = 0 ); + double get_gain( const std::string & name, size_t chan = 0 ); + + std::vector< std::string > get_antennas( size_t chan = 0 ); + std::string set_antenna( const std::string & antenna, size_t chan = 0 ); + std::string get_antenna( size_t chan = 0 ); private: static void _rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx); @@ -98,6 +120,7 @@ private: boost::circular_buffer _buf; boost::mutex _buf_mutex; boost::condition_variable _buf_cond; + bool _running; }; #endif /* INCLUDED_RTLSDR_SOURCE_C_H */