aboutsummaryrefslogtreecommitdiffstats
path: root/host/examples/txrx_loopback_to_file.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/examples/txrx_loopback_to_file.cpp')
-rw-r--r--host/examples/txrx_loopback_to_file.cpp447
1 files changed, 260 insertions, 187 deletions
diff --git a/host/examples/txrx_loopback_to_file.cpp b/host/examples/txrx_loopback_to_file.cpp
index cae69e043..d1d0ae615 100644
--- a/host/examples/txrx_loopback_to_file.cpp
+++ b/host/examples/txrx_loopback_to_file.cpp
@@ -6,21 +6,21 @@
//
#include "wavetable.hpp"
+#include <uhd/exception.hpp>
#include <uhd/types/tune_request.hpp>
-#include <uhd/utils/thread.hpp>
+#include <uhd/usrp/multi_usrp.hpp>
#include <uhd/utils/safe_main.hpp>
#include <uhd/utils/static.hpp>
-#include <uhd/usrp/multi_usrp.hpp>
-#include <uhd/exception.hpp>
-#include <boost/thread/thread.hpp>
-#include <boost/program_options.hpp>
-#include <boost/math/special_functions/round.hpp>
-#include <boost/format.hpp>
+#include <uhd/utils/thread.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
-#include <iostream>
-#include <fstream>
+#include <boost/format.hpp>
+#include <boost/math/special_functions/round.hpp>
+#include <boost/program_options.hpp>
+#include <boost/thread/thread.hpp>
#include <csignal>
+#include <fstream>
+#include <iostream>
namespace po = boost::program_options;
@@ -28,25 +28,26 @@ namespace po = boost::program_options;
* Signal handlers
**********************************************************************/
static bool stop_signal_called = false;
-void sig_int_handler(int){stop_signal_called = true;}
+void sig_int_handler(int)
+{
+ stop_signal_called = true;
+}
/***********************************************************************
* Utilities
**********************************************************************/
//! Change to filename, e.g. from usrp_samples.dat to usrp_samples.00.dat,
// but only if multiple names are to be generated.
-std::string generate_out_filename(const std::string &base_fn, size_t n_names, size_t this_name)
+std::string generate_out_filename(
+ const std::string& base_fn, size_t n_names, size_t this_name)
{
if (n_names == 1) {
return base_fn;
}
boost::filesystem::path base_fn_fp(base_fn);
- base_fn_fp.replace_extension(
- boost::filesystem::path(
- str(boost::format("%02d%s") % this_name % base_fn_fp.extension().string())
- )
- );
+ base_fn_fp.replace_extension(boost::filesystem::path(
+ str(boost::format("%02d%s") % this_name % base_fn_fp.extension().string())));
return base_fn_fp.string();
}
@@ -55,32 +56,31 @@ std::string generate_out_filename(const std::string &base_fn, size_t n_names, si
* transmit_worker function
* A function to be used as a boost::thread_group thread for transmitting
**********************************************************************/
-void transmit_worker(
- std::vector<std::complex<float> > buff,
+void transmit_worker(std::vector<std::complex<float>> buff,
wave_table_class wave_table,
uhd::tx_streamer::sptr tx_streamer,
uhd::tx_metadata_t metadata,
size_t step,
size_t index,
- int num_channels
-){
- std::vector<std::complex<float> *> buffs(num_channels, &buff.front());
-
- //send data until the signal handler gets called
- while(not stop_signal_called){
- //fill the buffer with the waveform
- for (size_t n = 0; n < buff.size(); n++){
+ int num_channels)
+{
+ std::vector<std::complex<float>*> buffs(num_channels, &buff.front());
+
+ // send data until the signal handler gets called
+ while (not stop_signal_called) {
+ // fill the buffer with the waveform
+ for (size_t n = 0; n < buff.size(); n++) {
buff[n] = wave_table(index += step);
}
- //send the entire contents of the buffer
+ // send the entire contents of the buffer
tx_streamer->send(buffs, buff.size(), metadata);
metadata.start_of_burst = false;
- metadata.has_time_spec = false;
+ metadata.has_time_spec = false;
}
- //send a mini EOB packet
+ // send a mini EOB packet
metadata.end_of_burst = true;
tx_streamer->send("", 0, metadata);
}
@@ -89,86 +89,88 @@ void transmit_worker(
/***********************************************************************
* recv_to_file function
**********************************************************************/
-template<typename samp_type> void recv_to_file(
- uhd::usrp::multi_usrp::sptr usrp,
- const std::string &cpu_format,
- const std::string &wire_format,
- const std::string &file,
+template <typename samp_type>
+void recv_to_file(uhd::usrp::multi_usrp::sptr usrp,
+ const std::string& cpu_format,
+ const std::string& wire_format,
+ const std::string& file,
size_t samps_per_buff,
int num_requested_samples,
double settling_time,
- std::vector<size_t> rx_channel_nums
-){
+ std::vector<size_t> rx_channel_nums)
+{
int num_total_samps = 0;
- //create a receive streamer
- uhd::stream_args_t stream_args(cpu_format,wire_format);
- stream_args.channels = rx_channel_nums;
+ // create a receive streamer
+ uhd::stream_args_t stream_args(cpu_format, wire_format);
+ stream_args.channels = rx_channel_nums;
uhd::rx_streamer::sptr rx_stream = usrp->get_rx_stream(stream_args);
// Prepare buffers for received samples and metadata
uhd::rx_metadata_t md;
- std::vector <std::vector< samp_type > > buffs(
- rx_channel_nums.size(), std::vector< samp_type >(samps_per_buff)
- );
- //create a vector of pointers to point to each of the channel buffers
- std::vector<samp_type *> buff_ptrs;
+ std::vector<std::vector<samp_type>> buffs(
+ rx_channel_nums.size(), std::vector<samp_type>(samps_per_buff));
+ // create a vector of pointers to point to each of the channel buffers
+ std::vector<samp_type*> buff_ptrs;
for (size_t i = 0; i < buffs.size(); i++) {
buff_ptrs.push_back(&buffs[i].front());
}
// Create one ofstream object per channel
// (use shared_ptr because ofstream is non-copyable)
- std::vector<boost::shared_ptr<std::ofstream> > outfiles;
+ std::vector<boost::shared_ptr<std::ofstream>> outfiles;
for (size_t i = 0; i < buffs.size(); i++) {
const std::string this_filename = generate_out_filename(file, buffs.size(), i);
- outfiles.push_back(boost::shared_ptr<std::ofstream>(new std::ofstream(this_filename.c_str(), std::ofstream::binary)));
+ outfiles.push_back(boost::shared_ptr<std::ofstream>(
+ new std::ofstream(this_filename.c_str(), std::ofstream::binary)));
}
UHD_ASSERT_THROW(outfiles.size() == buffs.size());
UHD_ASSERT_THROW(buffs.size() == rx_channel_nums.size());
bool overflow_message = true;
- double timeout = settling_time + 0.1f; //expected settling time + padding for first recv
-
- //setup streaming
- uhd::stream_cmd_t stream_cmd((num_requested_samples == 0)?
- uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS:
- uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE
- );
- stream_cmd.num_samps = num_requested_samples;
+ double timeout =
+ settling_time + 0.1f; // expected settling time + padding for first recv
+
+ // setup streaming
+ uhd::stream_cmd_t stream_cmd((num_requested_samples == 0)
+ ? uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS
+ : uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);
+ stream_cmd.num_samps = num_requested_samples;
stream_cmd.stream_now = false;
- stream_cmd.time_spec = uhd::time_spec_t(settling_time);
+ stream_cmd.time_spec = uhd::time_spec_t(settling_time);
rx_stream->issue_stream_cmd(stream_cmd);
- while(not stop_signal_called and (num_requested_samples > num_total_samps or num_requested_samples == 0)){
+ while (not stop_signal_called
+ and (num_requested_samples > num_total_samps or num_requested_samples == 0)) {
size_t num_rx_samps = rx_stream->recv(buff_ptrs, samps_per_buff, md, timeout);
- timeout = 0.1f; //small timeout for subsequent recv
+ timeout = 0.1f; // small timeout for subsequent recv
if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT) {
std::cout << boost::format("Timeout while streaming") << std::endl;
break;
}
- if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW){
- if (overflow_message){
+ if (md.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW) {
+ if (overflow_message) {
overflow_message = false;
- std::cerr << boost::format(
- "Got an overflow indication. Please consider the following:\n"
- " Your write medium must sustain a rate of %fMB/s.\n"
- " Dropped samples will not be written to the file.\n"
- " Please modify this example for your purposes.\n"
- " This message will not appear again.\n"
- ) % (usrp->get_rx_rate()*sizeof(samp_type)/1e6);
+ std::cerr
+ << boost::format(
+ "Got an overflow indication. Please consider the following:\n"
+ " Your write medium must sustain a rate of %fMB/s.\n"
+ " Dropped samples will not be written to the file.\n"
+ " Please modify this example for your purposes.\n"
+ " This message will not appear again.\n")
+ % (usrp->get_rx_rate() * sizeof(samp_type) / 1e6);
}
continue;
}
- if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE){
- throw std::runtime_error(str(boost::format(
- "Receiver error %s"
- ) % md.strerror()));
+ if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) {
+ throw std::runtime_error(
+ str(boost::format("Receiver error %s") % md.strerror()));
}
num_total_samps += num_rx_samps;
for (size_t i = 0; i < outfiles.size(); i++) {
- outfiles[i]->write((const char*) buff_ptrs[i], num_rx_samps*sizeof(samp_type));
+ outfiles[i]->write(
+ (const char*)buff_ptrs[i], num_rx_samps * sizeof(samp_type));
}
}
@@ -186,21 +188,22 @@ template<typename samp_type> void recv_to_file(
/***********************************************************************
* Main function
**********************************************************************/
-int UHD_SAFE_MAIN(int argc, char *argv[]){
+int UHD_SAFE_MAIN(int argc, char* argv[])
+{
uhd::set_thread_priority_safe();
- //transmit variables to be set by po
+ // transmit variables to be set by po
std::string tx_args, wave_type, tx_ant, tx_subdev, ref, otw, tx_channels;
double tx_rate, tx_freq, tx_gain, wave_freq, tx_bw;
float ampl;
- //receive variables to be set by po
+ // receive variables to be set by po
std::string rx_args, file, type, rx_ant, rx_subdev, rx_channels;
size_t total_num_samps, spb;
double rx_rate, rx_freq, rx_gain, rx_bw;
double settling;
- //setup the program options
+ // setup the program options
po::options_description desc("Allowed options");
// clang-format off
desc.add_options()
@@ -239,245 +242,315 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
- //print the help message
- if (vm.count("help")){
+ // print the help message
+ if (vm.count("help")) {
std::cout << boost::format("UHD TXRX Loopback to File %s") % desc << std::endl;
return ~0;
}
- //create a usrp device
+ // create a usrp device
std::cout << std::endl;
- std::cout << boost::format("Creating the transmit usrp device with: %s...") % tx_args << std::endl;
+ std::cout << boost::format("Creating the transmit usrp device with: %s...") % tx_args
+ << std::endl;
uhd::usrp::multi_usrp::sptr tx_usrp = uhd::usrp::multi_usrp::make(tx_args);
std::cout << std::endl;
- std::cout << boost::format("Creating the receive usrp device with: %s...") % rx_args << std::endl;
+ std::cout << boost::format("Creating the receive usrp device with: %s...") % rx_args
+ << std::endl;
uhd::usrp::multi_usrp::sptr rx_usrp = uhd::usrp::multi_usrp::make(rx_args);
- //always select the subdevice first, the channel mapping affects the other settings
- if (vm.count("tx-subdev")) tx_usrp->set_tx_subdev_spec(tx_subdev);
- if (vm.count("rx-subdev")) rx_usrp->set_rx_subdev_spec(rx_subdev);
+ // always select the subdevice first, the channel mapping affects the other settings
+ if (vm.count("tx-subdev"))
+ tx_usrp->set_tx_subdev_spec(tx_subdev);
+ if (vm.count("rx-subdev"))
+ rx_usrp->set_rx_subdev_spec(rx_subdev);
- //detect which channels to use
+ // detect which channels to use
std::vector<std::string> tx_channel_strings;
std::vector<size_t> tx_channel_nums;
boost::split(tx_channel_strings, tx_channels, boost::is_any_of("\"',"));
- for(size_t ch = 0; ch < tx_channel_strings.size(); ch++){
+ for (size_t ch = 0; ch < tx_channel_strings.size(); ch++) {
size_t chan = std::stoi(tx_channel_strings[ch]);
- if(chan >= tx_usrp->get_tx_num_channels()){
+ if (chan >= tx_usrp->get_tx_num_channels()) {
throw std::runtime_error("Invalid TX channel(s) specified.");
- }
- else tx_channel_nums.push_back(std::stoi(tx_channel_strings[ch]));
+ } else
+ tx_channel_nums.push_back(std::stoi(tx_channel_strings[ch]));
}
std::vector<std::string> rx_channel_strings;
std::vector<size_t> rx_channel_nums;
boost::split(rx_channel_strings, rx_channels, boost::is_any_of("\"',"));
- for(size_t ch = 0; ch < rx_channel_strings.size(); ch++){
+ for (size_t ch = 0; ch < rx_channel_strings.size(); ch++) {
size_t chan = std::stoi(rx_channel_strings[ch]);
- if(chan >= rx_usrp->get_rx_num_channels()){
+ if (chan >= rx_usrp->get_rx_num_channels()) {
throw std::runtime_error("Invalid RX channel(s) specified.");
- }
- else rx_channel_nums.push_back(std::stoi(rx_channel_strings[ch]));
+ } else
+ rx_channel_nums.push_back(std::stoi(rx_channel_strings[ch]));
}
- //Lock mboard clocks
+ // Lock mboard clocks
tx_usrp->set_clock_source(ref);
rx_usrp->set_clock_source(ref);
- std::cout << boost::format("Using TX Device: %s") % tx_usrp->get_pp_string() << std::endl;
- std::cout << boost::format("Using RX Device: %s") % rx_usrp->get_pp_string() << std::endl;
+ std::cout << boost::format("Using TX Device: %s") % tx_usrp->get_pp_string()
+ << std::endl;
+ std::cout << boost::format("Using RX Device: %s") % rx_usrp->get_pp_string()
+ << std::endl;
- //set the transmit sample rate
- if (not vm.count("tx-rate")){
- std::cerr << "Please specify the transmit sample rate with --tx-rate" << std::endl;
+ // set the transmit sample rate
+ if (not vm.count("tx-rate")) {
+ std::cerr << "Please specify the transmit sample rate with --tx-rate"
+ << std::endl;
return ~0;
}
- std::cout << boost::format("Setting TX Rate: %f Msps...") % (tx_rate/1e6) << std::endl;
+ std::cout << boost::format("Setting TX Rate: %f Msps...") % (tx_rate / 1e6)
+ << std::endl;
tx_usrp->set_tx_rate(tx_rate);
- std::cout << boost::format("Actual TX Rate: %f Msps...") % (tx_usrp->get_tx_rate()/1e6) << std::endl << std::endl;
+ std::cout << boost::format("Actual TX Rate: %f Msps...")
+ % (tx_usrp->get_tx_rate() / 1e6)
+ << std::endl
+ << std::endl;
- //set the receive sample rate
- if (not vm.count("rx-rate")){
+ // set the receive sample rate
+ if (not vm.count("rx-rate")) {
std::cerr << "Please specify the sample rate with --rx-rate" << std::endl;
return ~0;
}
- std::cout << boost::format("Setting RX Rate: %f Msps...") % (rx_rate/1e6) << std::endl;
+ std::cout << boost::format("Setting RX Rate: %f Msps...") % (rx_rate / 1e6)
+ << std::endl;
rx_usrp->set_rx_rate(rx_rate);
- std::cout << boost::format("Actual RX Rate: %f Msps...") % (rx_usrp->get_rx_rate()/1e6) << std::endl << std::endl;
-
- //set the transmit center frequency
- if (not vm.count("tx-freq")){
- std::cerr << "Please specify the transmit center frequency with --tx-freq" << std::endl;
+ std::cout << boost::format("Actual RX Rate: %f Msps...")
+ % (rx_usrp->get_rx_rate() / 1e6)
+ << std::endl
+ << std::endl;
+
+ // set the transmit center frequency
+ if (not vm.count("tx-freq")) {
+ std::cerr << "Please specify the transmit center frequency with --tx-freq"
+ << std::endl;
return ~0;
}
- for(size_t ch = 0; ch < tx_channel_nums.size(); ch++) {
+ for (size_t ch = 0; ch < tx_channel_nums.size(); ch++) {
size_t channel = tx_channel_nums[ch];
if (tx_channel_nums.size() > 1) {
std::cout << "Configuring TX Channel " << channel << std::endl;
}
- std::cout << boost::format("Setting TX Freq: %f MHz...") % (tx_freq/1e6) << std::endl;
+ std::cout << boost::format("Setting TX Freq: %f MHz...") % (tx_freq / 1e6)
+ << std::endl;
uhd::tune_request_t tx_tune_request(tx_freq);
- if(vm.count("tx-int-n")) tx_tune_request.args = uhd::device_addr_t("mode_n=integer");
+ if (vm.count("tx-int-n"))
+ tx_tune_request.args = uhd::device_addr_t("mode_n=integer");
tx_usrp->set_tx_freq(tx_tune_request, channel);
- std::cout << boost::format("Actual TX Freq: %f MHz...") % (tx_usrp->get_tx_freq(channel)/1e6) << std::endl << std::endl;
-
- //set the rf gain
- if (vm.count("tx-gain")){
- std::cout << boost::format("Setting TX Gain: %f dB...") % tx_gain << std::endl;
+ std::cout << boost::format("Actual TX Freq: %f MHz...")
+ % (tx_usrp->get_tx_freq(channel) / 1e6)
+ << std::endl
+ << std::endl;
+
+ // set the rf gain
+ if (vm.count("tx-gain")) {
+ std::cout << boost::format("Setting TX Gain: %f dB...") % tx_gain
+ << std::endl;
tx_usrp->set_tx_gain(tx_gain, channel);
- std::cout << boost::format("Actual TX Gain: %f dB...") % tx_usrp->get_tx_gain(channel) << std::endl << std::endl;
+ std::cout << boost::format("Actual TX Gain: %f dB...")
+ % tx_usrp->get_tx_gain(channel)
+ << std::endl
+ << std::endl;
}
- //set the analog frontend filter bandwidth
- if (vm.count("tx-bw")){
- std::cout << boost::format("Setting TX Bandwidth: %f MHz...") % tx_bw << std::endl;
+ // set the analog frontend filter bandwidth
+ if (vm.count("tx-bw")) {
+ std::cout << boost::format("Setting TX Bandwidth: %f MHz...") % tx_bw
+ << std::endl;
tx_usrp->set_tx_bandwidth(tx_bw, channel);
- std::cout << boost::format("Actual TX Bandwidth: %f MHz...") % tx_usrp->get_tx_bandwidth(channel) << std::endl << std::endl;
+ std::cout << boost::format("Actual TX Bandwidth: %f MHz...")
+ % tx_usrp->get_tx_bandwidth(channel)
+ << std::endl
+ << std::endl;
}
- //set the antenna
- if (vm.count("tx-ant")) tx_usrp->set_tx_antenna(tx_ant, channel);
+ // set the antenna
+ if (vm.count("tx-ant"))
+ tx_usrp->set_tx_antenna(tx_ant, channel);
}
- for(size_t ch = 0; ch < rx_channel_nums.size(); ch++) {
+ for (size_t ch = 0; ch < rx_channel_nums.size(); ch++) {
size_t channel = rx_channel_nums[ch];
if (rx_channel_nums.size() > 1) {
std::cout << "Configuring RX Channel " << channel << std::endl;
}
- //set the receive center frequency
- if (not vm.count("rx-freq")){
- std::cerr << "Please specify the center frequency with --rx-freq" << std::endl;
+ // set the receive center frequency
+ if (not vm.count("rx-freq")) {
+ std::cerr << "Please specify the center frequency with --rx-freq"
+ << std::endl;
return ~0;
}
- std::cout << boost::format("Setting RX Freq: %f MHz...") % (rx_freq/1e6) << std::endl;
+ std::cout << boost::format("Setting RX Freq: %f MHz...") % (rx_freq / 1e6)
+ << std::endl;
uhd::tune_request_t rx_tune_request(rx_freq);
- if(vm.count("rx-int-n")) rx_tune_request.args = uhd::device_addr_t("mode_n=integer");
+ if (vm.count("rx-int-n"))
+ rx_tune_request.args = uhd::device_addr_t("mode_n=integer");
rx_usrp->set_rx_freq(rx_tune_request, channel);
- std::cout << boost::format("Actual RX Freq: %f MHz...") % (rx_usrp->get_rx_freq(channel)/1e6) << std::endl << std::endl;
-
- //set the receive rf gain
- if (vm.count("rx-gain")){
- std::cout << boost::format("Setting RX Gain: %f dB...") % rx_gain << std::endl;
+ std::cout << boost::format("Actual RX Freq: %f MHz...")
+ % (rx_usrp->get_rx_freq(channel) / 1e6)
+ << std::endl
+ << std::endl;
+
+ // set the receive rf gain
+ if (vm.count("rx-gain")) {
+ std::cout << boost::format("Setting RX Gain: %f dB...") % rx_gain
+ << std::endl;
rx_usrp->set_rx_gain(rx_gain, channel);
- std::cout << boost::format("Actual RX Gain: %f dB...") % rx_usrp->get_rx_gain(channel) << std::endl << std::endl;
+ std::cout << boost::format("Actual RX Gain: %f dB...")
+ % rx_usrp->get_rx_gain(channel)
+ << std::endl
+ << std::endl;
}
- //set the receive analog frontend filter bandwidth
- if (vm.count("rx-bw")){
- std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (rx_bw/1e6) << std::endl;
+ // set the receive analog frontend filter bandwidth
+ if (vm.count("rx-bw")) {
+ std::cout << boost::format("Setting RX Bandwidth: %f MHz...") % (rx_bw / 1e6)
+ << std::endl;
rx_usrp->set_rx_bandwidth(rx_bw, channel);
- std::cout << boost::format("Actual RX Bandwidth: %f MHz...") % (rx_usrp->get_rx_bandwidth(channel)/1e6) << std::endl << std::endl;
+ std::cout << boost::format("Actual RX Bandwidth: %f MHz...")
+ % (rx_usrp->get_rx_bandwidth(channel) / 1e6)
+ << std::endl
+ << std::endl;
}
// set the receive antenna
- if (vm.count("rx-ant")) rx_usrp->set_rx_antenna(rx_ant, channel);
+ if (vm.count("rx-ant"))
+ rx_usrp->set_rx_antenna(rx_ant, channel);
}
- //for the const wave, set the wave freq for small samples per period
- if (wave_freq == 0 and wave_type == "CONST"){
- wave_freq = tx_usrp->get_tx_rate()/2;
+ // for the const wave, set the wave freq for small samples per period
+ if (wave_freq == 0 and wave_type == "CONST") {
+ wave_freq = tx_usrp->get_tx_rate() / 2;
}
- //error when the waveform is not possible to generate
- if (std::abs(wave_freq) > tx_usrp->get_tx_rate()/2){
+ // error when the waveform is not possible to generate
+ if (std::abs(wave_freq) > tx_usrp->get_tx_rate() / 2) {
throw std::runtime_error("wave freq out of Nyquist zone");
}
- if (tx_usrp->get_tx_rate()/std::abs(wave_freq) > wave_table_len/2){
+ if (tx_usrp->get_tx_rate() / std::abs(wave_freq) > wave_table_len / 2) {
throw std::runtime_error("wave freq too small for table");
}
- //pre-compute the waveform values
+ // pre-compute the waveform values
const wave_table_class wave_table(wave_type, ampl);
- const size_t step = boost::math::iround(wave_freq/tx_usrp->get_tx_rate() * wave_table_len);
+ const size_t step =
+ boost::math::iround(wave_freq / tx_usrp->get_tx_rate() * wave_table_len);
size_t index = 0;
- //create a transmit streamer
- //linearly map channels (index0 = channel0, index1 = channel1, ...)
+ // create a transmit streamer
+ // linearly map channels (index0 = channel0, index1 = channel1, ...)
uhd::stream_args_t stream_args("fc32", otw);
- stream_args.channels = tx_channel_nums;
+ stream_args.channels = tx_channel_nums;
uhd::tx_streamer::sptr tx_stream = tx_usrp->get_tx_stream(stream_args);
- //allocate a buffer which we re-use for each channel
- if (spb == 0) spb = tx_stream->get_max_num_samps()*10;
- std::vector<std::complex<float> > buff(spb);
+ // allocate a buffer which we re-use for each channel
+ if (spb == 0)
+ spb = tx_stream->get_max_num_samps() * 10;
+ std::vector<std::complex<float>> buff(spb);
int num_channels = tx_channel_nums.size();
- //setup the metadata flags
+ // setup the metadata flags
uhd::tx_metadata_t md;
md.start_of_burst = true;
md.end_of_burst = false;
md.has_time_spec = true;
- md.time_spec = uhd::time_spec_t(0.5); //give us 0.5 seconds to fill the tx buffers
+ md.time_spec = uhd::time_spec_t(0.5); // give us 0.5 seconds to fill the tx buffers
- //Check Ref and LO Lock detect
+ // Check Ref and LO Lock detect
std::vector<std::string> tx_sensor_names, rx_sensor_names;
tx_sensor_names = tx_usrp->get_tx_sensor_names(0);
- if (std::find(tx_sensor_names.begin(), tx_sensor_names.end(), "lo_locked") != tx_sensor_names.end()) {
- uhd::sensor_value_t lo_locked = tx_usrp->get_tx_sensor("lo_locked",0);
- std::cout << boost::format("Checking TX: %s ...") % lo_locked.to_pp_string() << std::endl;
+ if (std::find(tx_sensor_names.begin(), tx_sensor_names.end(), "lo_locked")
+ != tx_sensor_names.end()) {
+ uhd::sensor_value_t lo_locked = tx_usrp->get_tx_sensor("lo_locked", 0);
+ std::cout << boost::format("Checking TX: %s ...") % lo_locked.to_pp_string()
+ << std::endl;
UHD_ASSERT_THROW(lo_locked.to_bool());
}
rx_sensor_names = rx_usrp->get_rx_sensor_names(0);
- if (std::find(rx_sensor_names.begin(), rx_sensor_names.end(), "lo_locked") != rx_sensor_names.end()) {
- uhd::sensor_value_t lo_locked = rx_usrp->get_rx_sensor("lo_locked",0);
- std::cout << boost::format("Checking RX: %s ...") % lo_locked.to_pp_string() << std::endl;
+ if (std::find(rx_sensor_names.begin(), rx_sensor_names.end(), "lo_locked")
+ != rx_sensor_names.end()) {
+ uhd::sensor_value_t lo_locked = rx_usrp->get_rx_sensor("lo_locked", 0);
+ std::cout << boost::format("Checking RX: %s ...") % lo_locked.to_pp_string()
+ << std::endl;
UHD_ASSERT_THROW(lo_locked.to_bool());
}
tx_sensor_names = tx_usrp->get_mboard_sensor_names(0);
- if ((ref == "mimo") and (std::find(tx_sensor_names.begin(), tx_sensor_names.end(), "mimo_locked") != tx_sensor_names.end())) {
- uhd::sensor_value_t mimo_locked = tx_usrp->get_mboard_sensor("mimo_locked",0);
- std::cout << boost::format("Checking TX: %s ...") % mimo_locked.to_pp_string() << std::endl;
+ if ((ref == "mimo")
+ and (std::find(tx_sensor_names.begin(), tx_sensor_names.end(), "mimo_locked")
+ != tx_sensor_names.end())) {
+ uhd::sensor_value_t mimo_locked = tx_usrp->get_mboard_sensor("mimo_locked", 0);
+ std::cout << boost::format("Checking TX: %s ...") % mimo_locked.to_pp_string()
+ << std::endl;
UHD_ASSERT_THROW(mimo_locked.to_bool());
}
- if ((ref == "external") and (std::find(tx_sensor_names.begin(), tx_sensor_names.end(), "ref_locked") != tx_sensor_names.end())) {
- uhd::sensor_value_t ref_locked = tx_usrp->get_mboard_sensor("ref_locked",0);
- std::cout << boost::format("Checking TX: %s ...") % ref_locked.to_pp_string() << std::endl;
+ if ((ref == "external")
+ and (std::find(tx_sensor_names.begin(), tx_sensor_names.end(), "ref_locked")
+ != tx_sensor_names.end())) {
+ uhd::sensor_value_t ref_locked = tx_usrp->get_mboard_sensor("ref_locked", 0);
+ std::cout << boost::format("Checking TX: %s ...") % ref_locked.to_pp_string()
+ << std::endl;
UHD_ASSERT_THROW(ref_locked.to_bool());
}
rx_sensor_names = rx_usrp->get_mboard_sensor_names(0);
- if ((ref == "mimo") and (std::find(rx_sensor_names.begin(), rx_sensor_names.end(), "mimo_locked") != rx_sensor_names.end())) {
- uhd::sensor_value_t mimo_locked = rx_usrp->get_mboard_sensor("mimo_locked",0);
- std::cout << boost::format("Checking RX: %s ...") % mimo_locked.to_pp_string() << std::endl;
+ if ((ref == "mimo")
+ and (std::find(rx_sensor_names.begin(), rx_sensor_names.end(), "mimo_locked")
+ != rx_sensor_names.end())) {
+ uhd::sensor_value_t mimo_locked = rx_usrp->get_mboard_sensor("mimo_locked", 0);
+ std::cout << boost::format("Checking RX: %s ...") % mimo_locked.to_pp_string()
+ << std::endl;
UHD_ASSERT_THROW(mimo_locked.to_bool());
}
- if ((ref == "external") and (std::find(rx_sensor_names.begin(), rx_sensor_names.end(), "ref_locked") != rx_sensor_names.end())) {
- uhd::sensor_value_t ref_locked = rx_usrp->get_mboard_sensor("ref_locked",0);
- std::cout << boost::format("Checking RX: %s ...") % ref_locked.to_pp_string() << std::endl;
+ if ((ref == "external")
+ and (std::find(rx_sensor_names.begin(), rx_sensor_names.end(), "ref_locked")
+ != rx_sensor_names.end())) {
+ uhd::sensor_value_t ref_locked = rx_usrp->get_mboard_sensor("ref_locked", 0);
+ std::cout << boost::format("Checking RX: %s ...") % ref_locked.to_pp_string()
+ << std::endl;
UHD_ASSERT_THROW(ref_locked.to_bool());
}
- if (total_num_samps == 0){
+ if (total_num_samps == 0) {
std::signal(SIGINT, &sig_int_handler);
std::cout << "Press Ctrl + C to stop streaming..." << std::endl;
}
- //reset usrp time to prepare for transmit/receive
+ // reset usrp time to prepare for transmit/receive
std::cout << boost::format("Setting device timestamp to 0...") << std::endl;
tx_usrp->set_time_now(uhd::time_spec_t(0.0));
- //start transmit worker thread
+ // start transmit worker thread
boost::thread_group transmit_thread;
- transmit_thread.create_thread(boost::bind(&transmit_worker, buff, wave_table, tx_stream, md, step, index, num_channels));
-
- //recv to file
- if (type == "double") recv_to_file<std::complex<double> >(rx_usrp, "fc64", otw, file, spb, total_num_samps, settling, rx_channel_nums);
- else if (type == "float") recv_to_file<std::complex<float> >(rx_usrp, "fc32", otw, file, spb, total_num_samps, settling, rx_channel_nums);
- else if (type == "short") recv_to_file<std::complex<short> >(rx_usrp, "sc16", otw, file, spb, total_num_samps, settling, rx_channel_nums);
+ transmit_thread.create_thread(boost::bind(
+ &transmit_worker, buff, wave_table, tx_stream, md, step, index, num_channels));
+
+ // recv to file
+ if (type == "double")
+ recv_to_file<std::complex<double>>(
+ rx_usrp, "fc64", otw, file, spb, total_num_samps, settling, rx_channel_nums);
+ else if (type == "float")
+ recv_to_file<std::complex<float>>(
+ rx_usrp, "fc32", otw, file, spb, total_num_samps, settling, rx_channel_nums);
+ else if (type == "short")
+ recv_to_file<std::complex<short>>(
+ rx_usrp, "sc16", otw, file, spb, total_num_samps, settling, rx_channel_nums);
else {
- //clean up transmit worker
+ // clean up transmit worker
stop_signal_called = true;
transmit_thread.join_all();
throw std::runtime_error("Unknown type " + type);
}
- //clean up transmit worker
+ // clean up transmit worker
stop_signal_called = true;
transmit_thread.join_all();
- //finished
+ // finished
std::cout << std::endl << "Done!" << std::endl << std::endl;
return EXIT_SUCCESS;
}