diff options
Diffstat (limited to 'host/examples/replay_samples_from_file.cpp')
-rw-r--r-- | host/examples/replay_samples_from_file.cpp | 158 |
1 files changed, 98 insertions, 60 deletions
diff --git a/host/examples/replay_samples_from_file.cpp b/host/examples/replay_samples_from_file.cpp index 07691df2b..8f022b4f2 100644 --- a/host/examples/replay_samples_from_file.cpp +++ b/host/examples/replay_samples_from_file.cpp @@ -10,25 +10,23 @@ // It streams the file data to the Replay block, where it is recorded, then it // is played back to the radio. -#include <uhd/utils/safe_main.hpp> #include <uhd/device3.hpp> #include <uhd/rfnoc/radio_ctrl.hpp> #include <uhd/rfnoc/replay_block_ctrl.hpp> -#include <boost/program_options.hpp> +#include <uhd/utils/safe_main.hpp> #include <boost/format.hpp> -#include <fstream> +#include <boost/program_options.hpp> #include <csignal> +#include <fstream> #include <thread> - namespace po = boost::program_options; using std::cout; using std::endl; - /////////////////////////////////////////////////////////////////////////////// static volatile bool stop_signal_called = false; @@ -40,8 +38,7 @@ void sig_int_handler(int) } - -int UHD_SAFE_MAIN(int argc, char *argv[]) +int UHD_SAFE_MAIN(int argc, char* argv[]) { // We use sc16 in this example, but the replay block only uses 64-bit words // and is not aware of the CPU or wire format. @@ -49,10 +46,10 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) std::string cpu_format("sc16"); // Constants related to the Replay block - const size_t replay_word_size = 8; // Size of words used by replay block - const size_t bytes_per_sample = 4; // Complex signed 16-bit is 32 bits per sample - const size_t samples_per_word = 2; // Number of sc16 samples per word - const size_t replay_spp = 2000; // SC16 Samples per packet generated by Replay block + const size_t replay_word_size = 8; // Size of words used by replay block + const size_t bytes_per_sample = 4; // Complex signed 16-bit is 32 bits per sample + const size_t samples_per_word = 2; // Number of sc16 samples per word + const size_t replay_spp = 2000; // SC16 Samples per packet generated by Replay block /////////////////////////////////////////////////////////////////////////// @@ -89,9 +86,10 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) // Print help message if (vm.count("help")) { cout << boost::format("UHD/RFNoC Replay samples from file %s") % desc << endl; - cout - << "This application uses the Replay block to playback data from a file to a radio" << endl - << endl; + cout << "This application uses the Replay block to playback data from a file to " + "a radio" + << endl + << endl; return EXIT_FAILURE; } @@ -117,7 +115,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) return EXIT_FAILURE; } replay_ctrl = usrp->get_block_ctrl<uhd::rfnoc::replay_block_ctrl>(replay_ctrl_id); - std::cout << "Using replay block " << replay_id << ", channel " << replay_chan << std::endl; + std::cout << "Using replay block " << replay_id << ", channel " << replay_chan + << std::endl; /////////////////////////////////////////////////////////////////////////// @@ -130,37 +129,47 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) radio_ctrl->set_args(radio_args); // Set the center frequency - if (not vm.count("freq")){ + if (not vm.count("freq")) { std::cerr << "Please specify the center frequency with --freq" << std::endl; return EXIT_FAILURE; } - std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq/1e6) << std::endl; + std::cout << boost::format("Setting TX Freq: %f MHz...") % (freq / 1e6) << std::endl; radio_ctrl->set_tx_frequency(freq, radio_chan); - std::cout << boost::format("Actual TX Freq: %f MHz...") % (radio_ctrl->get_tx_frequency(radio_chan)/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual TX Freq: %f MHz...") + % (radio_ctrl->get_tx_frequency(radio_chan) / 1e6) + << std::endl + << std::endl; // Set the sample rate if (vm.count("rate")) { - std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl; + std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate / 1e6) + << std::endl; radio_ctrl->set_rate(rate); - std::cout << boost::format("Actual TX Rate: %f Msps...") % (radio_ctrl->get_rate()/1e6) << std::endl << std::endl; + std::cout << boost::format("Actual TX Rate: %f Msps...") + % (radio_ctrl->get_rate() / 1e6) + << std::endl + << std::endl; } // Set the RF gain - if (vm.count("gain")){ + if (vm.count("gain")) { std::cout << boost::format("Setting TX Gain: %f dB...") % gain << std::endl; radio_ctrl->set_tx_gain(gain, radio_chan); - std::cout << boost::format("Actual TX Gain: %f dB...") % radio_ctrl->get_tx_gain(radio_chan) << std::endl << std::endl; + std::cout << boost::format("Actual TX Gain: %f dB...") + % radio_ctrl->get_tx_gain(radio_chan) + << std::endl + << std::endl; } // Set the analog front-end filter bandwidth - if (vm.count("bw")){ - std::cout << boost::format("Setting TX Bandwidth: %f MHz...") - % (bw / 1e6) + if (vm.count("bw")) { + std::cout << boost::format("Setting TX Bandwidth: %f MHz...") % (bw / 1e6) << std::endl; radio_ctrl->set_tx_bandwidth(bw, radio_chan); std::cout << boost::format("Actual TX Bandwidth: %f MHz...") - % (radio_ctrl->get_tx_bandwidth(radio_chan) / 1e6) - << std::endl << std::endl; + % (radio_ctrl->get_tx_bandwidth(radio_chan) / 1e6) + << std::endl + << std::endl; } // Set the antenna @@ -172,13 +181,18 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// // Connect Replay block to radio uhd::rfnoc::graph::sptr replay_graph = usrp->create_graph("rfnoc_replay"); usrp->clear(); - std::cout << "Connecting " << replay_ctrl->get_block_id() << " ==> " << radio_ctrl->get_block_id() << std::endl; - replay_graph->connect(replay_ctrl->get_block_id(), replay_chan, radio_ctrl->get_block_id(), radio_chan, replay_spp); + std::cout << "Connecting " << replay_ctrl->get_block_id() << " ==> " + << radio_ctrl->get_block_id() << std::endl; + replay_graph->connect(replay_ctrl->get_block_id(), + replay_chan, + radio_ctrl->get_block_id(), + radio_chan, + replay_spp); // Inform replay block that it has an RX streamer connected to it replay_ctrl->set_rx_streamer(true, replay_chan); @@ -193,20 +207,20 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) uhd::tx_streamer::sptr tx_stream; uhd::tx_metadata_t tx_md; - streamer_args["block_id"] = replay_ctrl->get_block_id().to_string(); + streamer_args["block_id"] = replay_ctrl->get_block_id().to_string(); streamer_args["block_port"] = str(boost::format("%d") % replay_chan); - stream_args.args = streamer_args; - tx_stream = usrp->get_tx_stream(stream_args); + stream_args.args = streamer_args; + tx_stream = usrp->get_tx_stream(stream_args); // Make sure that streamer SPP is a multiple of the Replay block word size size_t tx_spp = tx_stream->get_max_num_samps(); - if(tx_spp % samples_per_word != 0) { + if (tx_spp % samples_per_word != 0) { // Round SPP down to a multiple of the word size tx_spp = (tx_spp / samples_per_word) * samples_per_word; tx_stream.reset(); streamer_args["spp"] = boost::lexical_cast<std::string>(tx_spp); - stream_args.args = streamer_args; - tx_stream = usrp->get_tx_stream(stream_args); + stream_args.args = streamer_args; + tx_stream = usrp->get_tx_stream(stream_args); } cout << "Using streamer args: " << stream_args.args.to_string() << endl; @@ -228,7 +242,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) infile.seekg(0, std::ios::beg); // Calculate the number of 64-bit words and samples to replay - size_t words_to_replay = file_size / replay_word_size; + size_t words_to_replay = file_size / replay_word_size; size_t samples_to_replay = words_to_replay * replay_word_size / bytes_per_sample; // Create buffer @@ -254,15 +268,26 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) replay_ctrl->set_words_per_packet(replay_spp / samples_per_word, replay_chan); // Display replay configuration - cout << boost::format("Replay file size: %d bytes (%d qwords, %d samples)") - % (words_to_replay * replay_word_size) % words_to_replay % samples_to_replay + cout << boost::format("Replay file size: %d bytes (%d qwords, %d samples)") + % (words_to_replay * replay_word_size) % words_to_replay + % samples_to_replay << endl; - cout << boost::format("Record base address: 0x%X") % replay_ctrl->get_record_addr(replay_chan) << endl; - cout << boost::format("Record buffer size: %d bytes") % replay_ctrl->get_record_size(replay_chan) << endl; - cout << boost::format("Record fullness: %d") % replay_ctrl->get_record_fullness(replay_chan) << endl; - cout << boost::format("Play base address: 0x%X") % replay_ctrl->get_play_addr(replay_chan) << endl; - cout << boost::format("Play buffer size: %d bytes") % replay_ctrl->get_play_size(replay_chan) << endl; + cout << boost::format("Record base address: 0x%X") + % replay_ctrl->get_record_addr(replay_chan) + << endl; + cout << boost::format("Record buffer size: %d bytes") + % replay_ctrl->get_record_size(replay_chan) + << endl; + cout << boost::format("Record fullness: %d") + % replay_ctrl->get_record_fullness(replay_chan) + << endl; + cout << boost::format("Play base address: 0x%X") + % replay_ctrl->get_play_addr(replay_chan) + << endl; + cout << boost::format("Play buffer size: %d bytes") + % replay_ctrl->get_play_size(replay_chan) + << endl; // Restart record buffer repeatedly until no new data appears on the Replay // block's input. This will flush any data that was buffered on the input. @@ -278,12 +303,13 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) start_time = std::chrono::system_clock::now(); do { fullness = replay_ctrl->get_record_fullness(replay_chan); - if (fullness != 0) break; + if (fullness != 0) + break; time_diff = std::chrono::system_clock::now() - start_time; time_diff = std::chrono::duration_cast<std::chrono::milliseconds>(time_diff); } while (time_diff.count() < 250); } while (fullness); - + /////////////////////////////////////////////////////////////////////////// // Send data to replay (record the data) @@ -291,10 +317,11 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) cout << "Sending data to be recorded..." << endl; tx_md.start_of_burst = true; tx_md.end_of_burst = true; - size_t num_tx_samps = tx_stream->send(tx_buf_ptr, samples_to_replay, tx_md); + size_t num_tx_samps = tx_stream->send(tx_buf_ptr, samples_to_replay, tx_md); if (num_tx_samps != samples_to_replay) { - cout << boost::format("ERROR: Unable to send %d samples") % samples_to_replay << endl; + cout << boost::format("ERROR: Unable to send %d samples") % samples_to_replay + << endl; return EXIT_FAILURE; } @@ -303,7 +330,9 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) // Wait for data to be stored in on-board memory cout << "Waiting for recording to complete..." << endl; - while (replay_ctrl->get_record_fullness(replay_chan) < words_to_replay*replay_word_size); + while (replay_ctrl->get_record_fullness(replay_chan) + < words_to_replay * replay_word_size) + ; /////////////////////////////////////////////////////////////////////////// @@ -314,15 +343,18 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) if (nsamps <= 0) { // Replay the entire buffer over and over stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS; - stream_cmd.num_samps = words_to_replay; - cout << boost::format("Issuing replay command for %d words in continuous mode...") % stream_cmd.num_samps << endl; - } - else { + stream_cmd.num_samps = words_to_replay; + cout << boost::format("Issuing replay command for %d words in continuous mode...") + % stream_cmd.num_samps + << endl; + } else { // Replay nsamps, wrapping back to the start of the buffer if nsamps is // larger than the buffer size. stream_cmd.stream_mode = uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE; - stream_cmd.num_samps = nsamps / samples_per_word; - cout << boost::format("Issuing replay command for %d words...") % stream_cmd.num_samps << endl; + stream_cmd.num_samps = nsamps / samples_per_word; + cout << boost::format("Issuing replay command for %d words...") + % stream_cmd.num_samps + << endl; } stream_cmd.stream_now = true; replay_ctrl->issue_stream_cmd(stream_cmd, replay_chan); @@ -335,7 +367,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) std::signal(SIGINT, &sig_int_handler); cout << "Replaying data (Press Ctrl+C to stop)..." << endl; - while (not stop_signal_called); + while (not stop_signal_called) + ; // Remove SIGINT handler std::signal(SIGINT, SIG_DFL); @@ -359,11 +392,16 @@ int UHD_SAFE_MAIN(int argc, char *argv[]) uint16_t prev_packet_count, packet_count; cout << "Waiting for replay data to flush... "; - prev_packet_count = replay_ctrl->sr_read64(uhd::rfnoc::SR_READBACK_REG_GLOBAL_PARAMS, replay_chan) >> 32; - while(true) { + prev_packet_count = + replay_ctrl->sr_read64(uhd::rfnoc::SR_READBACK_REG_GLOBAL_PARAMS, replay_chan) + >> 32; + while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); - packet_count = replay_ctrl->sr_read64(uhd::rfnoc::SR_READBACK_REG_GLOBAL_PARAMS, replay_chan) >> 32; - if (packet_count == prev_packet_count) break; + packet_count = + replay_ctrl->sr_read64(uhd::rfnoc::SR_READBACK_REG_GLOBAL_PARAMS, replay_chan) + >> 32; + if (packet_count == prev_packet_count) + break; prev_packet_count = packet_count; } |