aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri Stolnikov <horiz0n@gmx.net>2012-09-30 20:12:48 +0200
committerDimitri Stolnikov <horiz0n@gmx.net>2012-09-30 20:12:48 +0200
commit2878501284c9e0a85fd67cbf06f3a4f6c99336ad (patch)
treea3fc79c448b0a5c7c2b16ca46717ff82b130ed0e
parentc51b04ee745d0c4c685c5a8cc15bcf83a9f1ab1f (diff)
add support for MSi2500 based DVB-T dongles through libmirisdr
this has been tested with analog modes only and still has to be verified with the usual digital modes for proper implementation.
-rw-r--r--CMakeLists.txt1
-rw-r--r--cmake/Modules/FindLibMiriSDR.cmake27
-rw-r--r--grc/gen_osmosdr_blocks.py2
-rw-r--r--lib/CMakeLists.txt10
-rw-r--r--lib/config.h.in1
-rw-r--r--lib/miri/CMakeLists.txt37
-rw-r--r--lib/miri/miri_source_c.cc450
-rw-r--r--lib/miri/miri_source_c.h133
-rw-r--r--lib/osmosdr_device.cc9
-rw-r--r--lib/osmosdr_source_c_impl.cc22
10 files changed, 692 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bdcd563..1b1e371 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -114,6 +114,7 @@ find_package(GnuradioUHD)
find_package(GnuradioFCD)
find_package(LibOsmoSDR)
find_package(LibRTLSDR)
+find_package(LibMiriSDR)
if(NOT GRUEL_FOUND)
message(FATAL_ERROR "Gruel required to compile osmosdr")
diff --git a/cmake/Modules/FindLibMiriSDR.cmake b/cmake/Modules/FindLibMiriSDR.cmake
new file mode 100644
index 0000000..36040dd
--- /dev/null
+++ b/cmake/Modules/FindLibMiriSDR.cmake
@@ -0,0 +1,27 @@
+if(NOT LIBMIRISDR_FOUND)
+ pkg_check_modules (LIBMIRISDR_PKG libmirisdr)
+ find_path(LIBMIRISDR_INCLUDE_DIR NAMES mirisdr.h
+ PATHS
+ ${LIBMIRISDR_PKG_INCLUDE_DIRS}
+ /usr/include
+ /usr/local/include
+ )
+
+ find_library(LIBMIRISDR_LIBRARIES NAMES mirisdr
+ PATHS
+ ${LIBMIRISDR_PKG_LIBRARY_DIRS}
+ /usr/lib
+ /usr/local/lib
+ )
+
+if(LIBMIRISDR_INCLUDE_DIR AND LIBMIRISDR_LIBRARIES)
+ set(LIBMIRISDR_FOUND TRUE CACHE INTERNAL "libmirisdr found")
+ message(STATUS "Found libmirisdr: ${LIBMIRISDR_INCLUDE_DIR}, ${LIBMIRISDR_LIBRARIES}")
+else(LIBMIRISDR_INCLUDE_DIR AND LIBMIRISDR_LIBRARIES)
+ set(LIBMIRISDR_FOUND FALSE CACHE INTERNAL "libmirisdr found")
+ message(STATUS "libmirisdr not found.")
+endif(LIBMIRISDR_INCLUDE_DIR AND LIBMIRISDR_LIBRARIES)
+
+mark_as_advanced(LIBMIRISDR_INCLUDE_DIR LIBMIRISDR_LIBRARIES)
+
+endif(NOT LIBMIRISDR_FOUND)
diff --git a/grc/gen_osmosdr_blocks.py b/grc/gen_osmosdr_blocks.py
index 5c6f0ce..b07fa23 100644
--- a/grc/gen_osmosdr_blocks.py
+++ b/grc/gen_osmosdr_blocks.py
@@ -108,6 +108,7 @@ While primarily being developed for the OsmoSDR hardware, this block also suppor
* Ettus USRP Devices through Ettus UHD library
* RTL2832U based DVB-T dongles through librtlsdr
* rtl-tcp spectrum server (see librtlsdr project)
+ * MSi2500 based DVB-T dongles through libmirisdr
* gnuradio .cfile input through libgnuradio-core
By using the OsmoSDR block you can take advantage of a common software api in your application(s) independent of the underlying radio hardware.
@@ -121,6 +122,7 @@ Use the device id or name (if applicable) to specify a certain device or list of
Examples (some arguments may be optional):
fcd=0
+ miri=0
rtl=0,rtl_xtal=28.80001e6,tuner_xtal=26e6,buffers=64 ...
rtl_tcp=127.0.0.1:1234,psize=16384
uhd,serial=...,type=usrp1,mcr=52e6,nchan=2,subdev='\\\\'B:0 A:0\\\\'' ...
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 50c3387..494d498 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -108,6 +108,16 @@ GR_INCLUDE_SUBDIRECTORY(uhd)
endif(ENABLE_UHD)
########################################################################
+# Setup MiriSDR component
+########################################################################
+include(GrComponent)
+GR_REGISTER_COMPONENT("Osmocom MiriSDR" ENABLE_MIRI LIBMIRISDR_FOUND)
+
+if(ENABLE_MIRI)
+GR_INCLUDE_SUBDIRECTORY(miri)
+endif(ENABLE_MIRI)
+
+########################################################################
# Setup configuration file
########################################################################
ADD_DEFINITIONS(-DHAVE_CONFIG_H=1)
diff --git a/lib/config.h.in b/lib/config.h.in
index f48ee77..0ca2be2 100644
--- a/lib/config.h.in
+++ b/lib/config.h.in
@@ -7,5 +7,6 @@
#cmakedefine ENABLE_RTL
#cmakedefine ENABLE_RTL_TCP
#cmakedefine ENABLE_UHD
+#cmakedefine ENABLE_MIRI
#endif // CONFIG_H_IN
diff --git a/lib/miri/CMakeLists.txt b/lib/miri/CMakeLists.txt
new file mode 100644
index 0000000..b9c4b02
--- /dev/null
+++ b/lib/miri/CMakeLists.txt
@@ -0,0 +1,37 @@
+# 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.
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+
+include_directories(APPEND
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${LIBMIRISDR_INCLUDE_DIR}
+)
+
+set(mirisdr_srcs
+ ${CMAKE_CURRENT_SOURCE_DIR}/miri_source_c.cc
+)
+
+########################################################################
+# Append gnuradio-mirisdr library sources
+########################################################################
+list(APPEND gr_osmosdr_srcs ${mirisdr_srcs})
+list(APPEND gr_osmosdr_libs ${LIBMIRISDR_LIBRARIES})
diff --git a/lib/miri/miri_source_c.cc b/lib/miri/miri_source_c.cc
new file mode 100644
index 0000000..4cd0587
--- /dev/null
+++ b/lib/miri/miri_source_c.cc
@@ -0,0 +1,450 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net>
+ * Copyright 2012 Steve Markgraf <steve@steve-m.de>
+ *
+ * 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 "miri_source_c.h"
+#include <gr_io_signature.h>
+
+#include <boost/assign.hpp>
+#include <boost/format.hpp>
+
+#include <stdexcept>
+#include <iostream>
+#include <stdio.h>
+
+#include <mirisdr.h>
+
+#include <osmosdr_arg_helpers.h>
+
+using namespace boost::assign;
+
+#define BUF_SIZE 2304 * 8 * 2
+#define BUF_NUM 32
+#define BUF_SKIP 1 // buffers to skip due to garbage
+
+#define BYTES_PER_SAMPLE 4 // mirisdr device delivers 16 bit signed IQ data
+ // containing 12 bits of information
+
+/*
+ * Create a new instance of miri_source_c and return
+ * a boost shared_ptr. This is effectively the public constructor.
+ */
+miri_source_c_sptr
+make_miri_source_c (const std::string &args)
+{
+ return gnuradio::get_initial_sptr(new miri_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 0 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
+ */
+miri_source_c::miri_source_c (const std::string &args)
+ : gr_sync_block ("miri_source_c",
+ gr_make_io_signature (MIN_IN, MAX_IN, sizeof (gr_complex)),
+ gr_make_io_signature (MIN_OUT, MAX_OUT, sizeof (gr_complex))),
+ _running(true),
+ _auto_gain(false),
+ _skipped(0)
+{
+ int ret;
+ unsigned int dev_index = 0;
+
+ dict_t dict = params_to_dict(args);
+
+ if (dict.count("miri"))
+ dev_index = boost::lexical_cast< unsigned int >( dict["miri"] );
+
+ _buf_num = BUF_NUM;
+ _buf_head = _buf_used = _buf_offset = 0;
+ _samp_avail = BUF_SIZE / BYTES_PER_SAMPLE;
+
+ if (dict.count("buffers")) {
+ _buf_num = (unsigned int)boost::lexical_cast< double >( dict["buffers"] );
+ if (0 == _buf_num)
+ _buf_num = BUF_NUM;
+ std::cerr << "Using " << _buf_num << " buffers of size " << BUF_SIZE << "."
+ << std::endl;
+ }
+
+ if ( dev_index >= mirisdr_get_device_count() )
+ throw std::runtime_error("Wrong mirisdr device index given.");
+
+ std::cerr << "Using device #" << dev_index << ": "
+ << mirisdr_get_device_name(dev_index)
+ << std::endl;
+
+ _dev = NULL;
+ ret = mirisdr_open( &_dev, dev_index );
+ if (ret < 0)
+ throw std::runtime_error("Failed to open mirisdr device.");
+#if 0
+ ret = mirisdr_set_sample_rate( _dev, 500000 );
+ if (ret < 0)
+ throw std::runtime_error("Failed to set default samplerate.");
+
+ ret = mirisdr_set_tuner_gain_mode(_dev, int(!_auto_gain));
+ if (ret < 0)
+ throw std::runtime_error("Failed to enable manual gain mode.");
+#endif
+ ret = mirisdr_reset_buffer( _dev );
+ if (ret < 0)
+ throw std::runtime_error("Failed to reset usb buffers.");
+
+ _buf = (unsigned short **) malloc(_buf_num * sizeof(unsigned short *));
+
+ if (_buf) {
+ for(unsigned int i = 0; i < _buf_num; ++i)
+ _buf[i] = (unsigned short *) malloc(BUF_SIZE);
+ }
+
+ _thread = gruel::thread(_mirisdr_wait, this);
+}
+
+/*
+ * Our virtual destructor.
+ */
+miri_source_c::~miri_source_c ()
+{
+ if (_dev) {
+ _running = false;
+ mirisdr_cancel_async( _dev );
+ _thread.join();
+ mirisdr_close( _dev );
+ _dev = NULL;
+ }
+
+ if (_buf) {
+ for(unsigned int i = 0; i < _buf_num; ++i) {
+ if (_buf[i])
+ free(_buf[i]);
+ }
+
+ free(_buf);
+ _buf = NULL;
+ }
+}
+
+void miri_source_c::_mirisdr_callback(unsigned char *buf, uint32_t len, void *ctx)
+{
+ miri_source_c *obj = (miri_source_c *)ctx;
+ obj->mirisdr_callback(buf, len);
+}
+
+void miri_source_c::mirisdr_callback(unsigned char *buf, uint32_t len)
+{
+ if (_skipped < BUF_SKIP) {
+ _skipped++;
+ return;
+ }
+
+ {
+ boost::mutex::scoped_lock lock( _buf_mutex );
+
+ int buf_tail = (_buf_head + _buf_used) % _buf_num;
+ memcpy(_buf[buf_tail], buf, len);
+
+ if (_buf_used == _buf_num) {
+ std::cerr << "O" << std::flush;
+ _buf_head = (_buf_head + 1) % _buf_num;
+ } else {
+ _buf_used++;
+ }
+ }
+
+ _buf_cond.notify_one();
+}
+
+void miri_source_c::_mirisdr_wait(miri_source_c *obj)
+{
+ obj->mirisdr_wait();
+}
+
+void miri_source_c::mirisdr_wait()
+{
+ int ret = mirisdr_read_async( _dev, _mirisdr_callback, (void *)this, 0, BUF_SIZE );
+
+ _running = false;
+
+ if ( ret != 0 )
+ std::cerr << "mirisdr_read_async returned with " << ret << std::endl;
+}
+
+int miri_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];
+
+ {
+ boost::mutex::scoped_lock lock( _buf_mutex );
+
+ while (_buf_used < 3 && _running) // collect at least 3 buffers
+ _buf_cond.wait( lock );
+ }
+
+ if (!_running)
+ return WORK_DONE;
+
+ short *buf = (short *)_buf[_buf_head] + _buf_offset;
+
+ if (noutput_items <= _samp_avail) {
+ for (int i = 0; i < noutput_items; i++)
+ *out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/4096.0f),
+ float(*(buf + i * 2 + 1)) * (1.0f/4096.0f) );
+
+ _buf_offset += noutput_items * 2;
+ _samp_avail -= noutput_items;
+ } else {
+ for (int i = 0; i < _samp_avail; i++)
+ *out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/4096.0f),
+ float(*(buf + i * 2 + 1)) * (1.0f/4096.0f) );
+
+ {
+ boost::mutex::scoped_lock lock( _buf_mutex );
+
+ _buf_head = (_buf_head + 1) % _buf_num;
+ _buf_used--;
+ }
+
+ buf = (short *)_buf[_buf_head];
+
+ int remaining = noutput_items - _samp_avail;
+
+ for (int i = 0; i < remaining; i++)
+ *out++ = gr_complex( float(*(buf + i * 2 + 0)) * (1.0f/4096.0f),
+ float(*(buf + i * 2 + 1)) * (1.0f/4096.0f) );
+
+ _buf_offset = remaining * 2;
+ _samp_avail = (BUF_SIZE / BYTES_PER_SAMPLE) - remaining;
+ }
+
+ return noutput_items;
+}
+
+std::vector<std::string> miri_source_c::get_devices()
+{
+ std::vector<std::string> devices;
+
+ for (unsigned int i = 0; i < mirisdr_get_device_count(); i++) {
+ std::string args = "miri=" + boost::lexical_cast< std::string >( i );
+ args += ",label='" + std::string(mirisdr_get_device_name( i )) + "'";
+ devices.push_back( args );
+ }
+
+ return devices;
+}
+
+size_t miri_source_c::get_num_channels()
+{
+ return 1;
+}
+
+osmosdr::meta_range_t miri_source_c::get_sample_rates()
+{
+ osmosdr::meta_range_t range;
+
+ if (_dev) {
+ int count = mirisdr_get_sample_rates(_dev, NULL);
+ if (count > 0) {
+ uint32_t* rates = new uint32_t[ count ];
+ count = mirisdr_get_sample_rates(_dev, rates);
+ for (int i = 0; i < count; i++)
+ range += osmosdr::range_t( rates[i] );
+ delete[] rates;
+ }
+ }
+
+ return range;
+}
+
+double miri_source_c::set_sample_rate(double rate)
+{
+ if (_dev) {
+ mirisdr_set_sample_rate( _dev, (uint32_t)rate );
+ }
+
+ return get_sample_rate();
+}
+
+double miri_source_c::get_sample_rate()
+{
+ if (_dev)
+ return (double)mirisdr_get_sample_rate( _dev );
+
+ return 0;
+}
+
+osmosdr::freq_range_t miri_source_c::get_freq_range( size_t chan )
+{
+ osmosdr::freq_range_t range;
+
+ range += osmosdr::range_t( 150e3, 30e6 ); /* LW/MW/SW (150 kHz - 30 MHz) */
+ range += osmosdr::range_t( 64e6, 108e6 ); /* VHF Band II (64 - 108 MHz) */
+ range += osmosdr::range_t( 162e6, 240e6 ); /* Band III (162 - 240 MHz) */
+ range += osmosdr::range_t( 470e6, 960e6 ); /* Band IV/V (470 - 960 MHz) */
+ range += osmosdr::range_t( 1450e6, 1675e6 ); /* L-Band (1450 - 1675 MHz) */
+
+ return range;
+}
+
+double miri_source_c::set_center_freq( double freq, size_t chan )
+{
+ if (_dev)
+ mirisdr_set_center_freq( _dev, (uint32_t)freq );
+
+ return get_center_freq( chan );
+}
+
+double miri_source_c::get_center_freq( size_t chan )
+{
+ if (_dev)
+ return (double)mirisdr_get_center_freq( _dev );
+
+ return 0;
+}
+
+double miri_source_c::set_freq_corr( double ppm, size_t chan )
+{
+ return get_freq_corr( chan );
+}
+
+double miri_source_c::get_freq_corr( size_t chan )
+{
+ return 0;
+}
+
+std::vector<std::string> miri_source_c::get_gain_names( size_t chan )
+{
+ std::vector< std::string > gains;
+
+ gains += "LNA";
+
+ return gains;
+}
+
+osmosdr::gain_range_t miri_source_c::get_gain_range( size_t chan )
+{
+ osmosdr::gain_range_t range;
+
+ if (_dev) {
+ int count = mirisdr_get_tuner_gains(_dev, NULL);
+ if (count > 0) {
+ int* gains = new int[ count ];
+ count = mirisdr_get_tuner_gains(_dev, gains);
+ for (int i = 0; i < count; i++)
+ range += osmosdr::range_t( gains[i] / 10.0 );
+ delete[] gains;
+ }
+ }
+
+ return range;
+}
+
+osmosdr::gain_range_t miri_source_c::get_gain_range( const std::string & name, size_t chan )
+{
+ return get_gain_range( chan );
+}
+
+bool miri_source_c::set_gain_mode( bool automatic, size_t chan )
+{
+ if (_dev) {
+ if (!mirisdr_set_tuner_gain_mode(_dev, int(!automatic))) {
+ _auto_gain = automatic;
+ }
+ }
+
+ return get_gain_mode(chan);
+}
+
+bool miri_source_c::get_gain_mode( size_t chan )
+{
+ return _auto_gain;
+}
+
+double miri_source_c::set_gain( double gain, size_t chan )
+{
+ osmosdr::gain_range_t rf_gains = miri_source_c::get_gain_range( chan );
+
+ if (_dev) {
+ mirisdr_set_tuner_gain( _dev, int(rf_gains.clip(gain) * 10.0) );
+ }
+
+ return get_gain( chan );
+}
+
+double miri_source_c::set_gain( double gain, const std::string & name, size_t chan)
+{
+ return set_gain( gain, chan );
+}
+
+double miri_source_c::get_gain( size_t chan )
+{
+ if ( _dev )
+ return ((double)mirisdr_get_tuner_gain( _dev )) / 10.0;
+
+ return 0;
+}
+
+double miri_source_c::get_gain( const std::string & name, size_t chan )
+{
+ return get_gain( chan );
+}
+
+std::vector< std::string > miri_source_c::get_antennas( size_t chan )
+{
+ std::vector< std::string > antennas;
+
+ antennas += get_antenna( chan );
+
+ return antennas;
+}
+
+std::string miri_source_c::set_antenna( const std::string & antenna, size_t chan )
+{
+ return get_antenna( chan );
+}
+
+std::string miri_source_c::get_antenna( size_t chan )
+{
+ return "ANT";
+}
diff --git a/lib/miri/miri_source_c.h b/lib/miri/miri_source_c.h
new file mode 100644
index 0000000..8e00efa
--- /dev/null
+++ b/lib/miri/miri_source_c.h
@@ -0,0 +1,133 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 Dimitri Stolnikov <horiz0n@gmx.net>
+ *
+ * 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_MIRI_SOURCE_C_H
+#define INCLUDED_MIRI_SOURCE_C_H
+
+#include <gr_sync_block.h>
+
+#include <gruel/thread.h>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+
+#include "osmosdr_src_iface.h"
+
+class miri_source_c;
+typedef struct mirisdr_dev mirisdr_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<miri_source_c> miri_source_c_sptr;
+
+/*!
+ * \brief Return a shared_ptr to a new instance of miri_source_c.
+ *
+ * To avoid accidental use of raw pointers, miri_source_c's
+ * constructor is private. make_miri_source_c is the public
+ * interface for creating new instances.
+ */
+miri_source_c_sptr make_miri_source_c (const std::string & args = "");
+
+/*!
+ * \brief Provides a stream of complex samples.
+ * \ingroup block
+ */
+class miri_source_c :
+ public gr_sync_block,
+ public osmosdr_src_iface
+{
+private:
+ // The friend declaration allows make_miri_source_c to
+ // access the private constructor.
+
+ friend miri_source_c_sptr make_miri_source_c (const std::string & args);
+
+ /*!
+ * \brief Provides a stream of complex samples.
+ */
+ miri_source_c (const std::string & args); // private constructor
+
+ public:
+ ~miri_source_c (); // public destructor
+
+ int work( int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items );
+
+ static std::vector< std::string > get_devices();
+
+ 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_corr( double ppm, size_t chan = 0 );
+ double get_freq_corr( size_t chan = 0 );
+
+ std::vector<std::string> 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 );
+ bool set_gain_mode( bool automatic, size_t chan = 0 );
+ bool get_gain_mode( 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 _mirisdr_callback(unsigned char *buf, uint32_t len, void *ctx);
+ void mirisdr_callback(unsigned char *buf, uint32_t len);
+ static void _mirisdr_wait(miri_source_c *obj);
+ void mirisdr_wait();
+
+ mirisdr_dev_t *_dev;
+ gruel::thread _thread;
+ unsigned short **_buf;
+ unsigned int _buf_num;
+ unsigned int _buf_head;
+ unsigned int _buf_used;
+ boost::mutex _buf_mutex;
+ boost::condition_variable _buf_cond;
+ bool _running;
+
+ unsigned int _buf_offset;
+ int _samp_avail;
+
+ bool _auto_gain;
+ unsigned int _skipped;
+};
+
+#endif /* INCLUDED_MIRI_SOURCE_C_H */
diff --git a/lib/osmosdr_device.cc b/lib/osmosdr_device.cc
index 11d4c0b..aaef32a 100644
--- a/lib/osmosdr_device.cc
+++ b/lib/osmosdr_device.cc
@@ -34,6 +34,7 @@
#define ENABLE_FCD
#define ENABLE_RTL
#define ENABLE_UHD
+#define ENABLE_MIRI
*/
#ifdef ENABLE_OSMOSDR
#include <osmosdr_src_c.h>
@@ -51,6 +52,10 @@
#include <uhd_source_c.h>
#endif
+#ifdef ENABLE_MIRI
+#include <miri_source_c.h>
+#endif
+
#include "osmosdr_arg_helpers.h"
using namespace osmosdr;
@@ -118,6 +123,10 @@ devices_t device::find(const device_t &hint)
BOOST_FOREACH( std::string dev, uhd_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
+#ifdef ENABLE_MIRI
+ BOOST_FOREACH( std::string dev, miri_source_c::get_devices() )
+ devices.push_back( device_t(dev) );
+#endif
return devices;
}
diff --git a/lib/osmosdr_source_c_impl.cc b/lib/osmosdr_source_c_impl.cc
index 0125294..4bbd141 100644
--- a/lib/osmosdr_source_c_impl.cc
+++ b/lib/osmosdr_source_c_impl.cc
@@ -54,6 +54,10 @@
#include <uhd_source_c.h>
#endif
+#ifdef ENABLE_MIRI
+#include <miri_source_c.h>
+#endif
+
#include <osmosdr_arg_helpers.h>
/* This avoids throws in ctor of gr_hier_block2, as gnuradio is unable to deal
@@ -99,6 +103,9 @@ osmosdr_source_c_impl::osmosdr_source_c_impl (const std::string &args)
#ifdef ENABLE_UHD
dev_types.push_back("uhd");
#endif
+#ifdef ENABLE_MIRI
+ dev_types.push_back("miri");
+#endif
std::cerr << "gr-osmosdr supported device types: ";
BOOST_FOREACH(std::string dev_type, dev_types)
@@ -134,6 +141,10 @@ osmosdr_source_c_impl::osmosdr_source_c_impl (const std::string &args)
BOOST_FOREACH( std::string dev, uhd_source_c::get_devices() )
dev_list.push_back( dev );
#endif
+#ifdef ENABLE_MIRI
+ BOOST_FOREACH( std::string dev, miri_source_c::get_devices() )
+ dev_list.push_back( dev );
+#endif
// std::cerr << std::endl;
// BOOST_FOREACH( std::string dev, dev_list )
// std::cerr << "'" << dev << "'" << std::endl;
@@ -206,6 +217,17 @@ osmosdr_source_c_impl::osmosdr_source_c_impl (const std::string &args)
_devs.push_back( src.get() );
}
#endif
+
+#ifdef ENABLE_MIRI
+ if ( dict.count("miri") ) {
+ miri_source_c_sptr src = make_miri_source_c( arg );
+
+ for (size_t i = 0; i < src->get_num_channels(); i++)
+ connect(src, i, self(), channel++);
+
+ _devs.push_back( src.get() );
+ }
+#endif
}
if (!_devs.size())