diff options
Diffstat (limited to 'gr-wxgui/lib')
-rw-r--r-- | gr-wxgui/lib/CMakeLists.txt | 77 | ||||
-rw-r--r-- | gr-wxgui/lib/gnuradio-wxgui.rc.in | 54 | ||||
-rw-r--r-- | gr-wxgui/lib/histo_sink_f_impl.cc | 186 | ||||
-rw-r--r-- | gr-wxgui/lib/histo_sink_f_impl.h | 63 | ||||
-rw-r--r-- | gr-wxgui/lib/oscope_guts.cc | 439 | ||||
-rw-r--r-- | gr-wxgui/lib/oscope_sink_f_impl.cc | 83 | ||||
-rw-r--r-- | gr-wxgui/lib/oscope_sink_f_impl.h | 51 | ||||
-rw-r--r-- | gr-wxgui/lib/oscope_sink_x.cc | 161 |
8 files changed, 1114 insertions, 0 deletions
diff --git a/gr-wxgui/lib/CMakeLists.txt b/gr-wxgui/lib/CMakeLists.txt new file mode 100644 index 0000000000..c33a7b9a33 --- /dev/null +++ b/gr-wxgui/lib/CMakeLists.txt @@ -0,0 +1,77 @@ +# Copyright 2012-2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Setup the include and linker paths +######################################################################## +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/../include + ${GR_WXGUI_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} + ${VOLK_INCLUDE_DIRS} + ${Boost_INCLUDE_DIRS} +) + +link_directories(${Boost_LIBRARY_DIRS}) + +if(ENABLE_GR_CTRLPORT) + ADD_DEFINITIONS(-DGR_CTRLPORT) + include_directories(${ICE_INCLUDE_DIR}) +endif(ENABLE_GR_CTRLPORT) + +######################################################################## +# Setup library +######################################################################## +list(APPEND gr_wxgui_sources + histo_sink_f_impl.cc + oscope_guts.cc + oscope_sink_x.cc + oscope_sink_f_impl.cc +) + +#Add Windows DLL resource file if using MSVC +IF(MSVC) + include(${CMAKE_SOURCE_DIR}/cmake/Modules/GrVersion.cmake) + + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/gnuradio-wxgui.rc.in + ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-wxgui.rc + @ONLY) + + list(APPEND gr_wxgui_sources + ${CMAKE_CURRENT_BINARY_DIR}/gnuradio-wxgui.rc + ) +ENDIF(MSVC) + +list(APPEND wxgui_libs + gnuradio-runtime + volk + ${Boost_LIBRARIES} + ${BLOCKS_LIBRARIES} + ${LOG4CPP_LIBRARIES} +) + +add_library(gnuradio-wxgui SHARED ${gr_wxgui_sources}) + +target_link_libraries(gnuradio-wxgui ${wxgui_libs}) +GR_LIBRARY_FOO(gnuradio-wxgui + RUNTIME_COMPONENT "wxgui_runtime" + DEVEL_COMPONENT "wxgui_devel") diff --git a/gr-wxgui/lib/gnuradio-wxgui.rc.in b/gr-wxgui/lib/gnuradio-wxgui.rc.in new file mode 100644 index 0000000000..126db75091 --- /dev/null +++ b/gr-wxgui/lib/gnuradio-wxgui.rc.in @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 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. + */ +#include <afxres.h> + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @MAJOR_VERSION@,@API_COMPAT@,@RC_MINOR_VERSION@,@RC_MAINT_VERSION@ + PRODUCTVERSION @MAJOR_VERSION@,@API_COMPAT@,@RC_MINOR_VERSION@,@RC_MAINT_VERSION@ + FILEFLAGSMASK 0x3fL +#ifndef NDEBUG + FILEFLAGS 0x0L +#else + FILEFLAGS 0x1L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT2_DRV_INSTALLABLE + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "gnuradio-blocks" + VALUE "FileVersion", "@VERSION@" + VALUE "InternalName", "gnuradio-blocks.dll" + VALUE "LegalCopyright", "Licensed under GPLv3 or any later version" + VALUE "OriginalFilename", "gnuradio-blocks.dll" + VALUE "ProductName", "gnuradio-blocks" + VALUE "ProductVersion", "@VERSION@" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END + END diff --git a/gr-wxgui/lib/histo_sink_f_impl.cc b/gr-wxgui/lib/histo_sink_f_impl.cc new file mode 100644 index 0000000000..9b168de547 --- /dev/null +++ b/gr-wxgui/lib/histo_sink_f_impl.cc @@ -0,0 +1,186 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009-2011,2013 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "histo_sink_f_impl.h" +#include <gr_io_signature.h> +#include <boost/math/special_functions/round.hpp> + +namespace gr { + namespace wxgui { + + static float get_clean_num(float num) + { + if(num == 0) + return 0; + /* extract sign and exponent from num */ + int sign = (num < 0) ? -1 : 1; num = fabs(num); + float exponent = floor(log10(num)); + /* search for closest number with base 1, 2, 5, 10 */ + float closest_num = 10*pow(10, exponent); + if(fabs(num - 1*pow(10, exponent)) < fabs(num - closest_num)) + closest_num = 1*pow(10, exponent); + if(fabs(num - 2*pow(10, exponent)) < fabs(num - closest_num)) + closest_num = 2*pow(10, exponent); + if(fabs(num - 5*pow(10, exponent)) < fabs(num - closest_num)) + closest_num = 5*pow(10, exponent); + return sign*closest_num; + } + + histo_sink_f::sptr + histo_sink_f::make(gr_msg_queue_sptr msgq) + { + return gnuradio::get_initial_sptr + (new histo_sink_f_impl(msgq)); + } + + histo_sink_f_impl::histo_sink_f_impl(gr_msg_queue_sptr msgq) + : gr_sync_block("histo_sink_f", + gr_make_io_signature(1, 1, sizeof(float)), + gr_make_io_signature(0, 0, 0)), + d_msgq(msgq), d_num_bins(11), d_frame_size(1000), + d_sample_count(0), d_bins(NULL), d_samps(NULL) + { + //allocate arrays and clear + set_num_bins(d_num_bins); + set_frame_size(d_frame_size); + } + + histo_sink_f_impl::~histo_sink_f_impl(void) + { + delete [] d_samps; + delete [] d_bins; + } + + int + histo_sink_f_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const float *in = (const float*)input_items[0]; + gr::thread::scoped_lock guard(d_mutex); // hold mutex for duration of this function + for(unsigned int i = 0; i < (unsigned int)noutput_items; i++) { + d_samps[d_sample_count] = in[i]; + d_sample_count++; + /* processed a frame? */ + if(d_sample_count == d_frame_size) { + send_frame(); + clear(); + } + } + return noutput_items; + } + + void + histo_sink_f_impl::send_frame(void) + { + /* output queue full, drop the data */ + if(d_msgq->full_p()) + return; + /* find the minimum and maximum */ + float minimum = d_samps[0]; + float maximum = d_samps[0]; + for(unsigned int i = 0; i < d_frame_size; i++) { + if(d_samps[i] < minimum) minimum = d_samps[i]; + if(d_samps[i] > maximum) maximum = d_samps[i]; + } + minimum = get_clean_num(minimum); + maximum = get_clean_num(maximum); + if(minimum == maximum || minimum > maximum) + return; //useless data or screw up? + /* load the bins */ + int index; + float bin_width = (maximum - minimum)/(d_num_bins-1); + for(unsigned int i = 0; i < d_sample_count; i++) { + index = boost::math::iround((d_samps[i] - minimum)/bin_width); + /* ensure the index range in case a small floating point error is involed */ + if(index < 0) + index = 0; + if(index >= (int)d_num_bins) + index = d_num_bins-1; + d_bins[index]++; + } + /* Build a message to hold the output records */ + gr_message_sptr msg = gr_make_message(0, minimum, maximum, d_num_bins*sizeof(float)); + float *out = (float *)msg->msg(); // get pointer to raw message buffer + /* normalize the bins and put into message */ + for(unsigned int i = 0; i < d_num_bins; i++) { + out[i] = ((float)d_bins[i])/d_frame_size; + } + /* send the message */ + d_msgq->handle(msg); + } + + void + histo_sink_f_impl::clear(void) + { + d_sample_count = 0; + /* zero the bins */ + for(unsigned int i = 0; i < d_num_bins; i++) { + d_bins[i] = 0; + } + } + + /************************************************** + * Getters + **************************************************/ + unsigned int + histo_sink_f_impl::get_frame_size(void) + { + return d_frame_size; + } + + unsigned int + histo_sink_f_impl::get_num_bins(void) + { + return d_num_bins; + } + + /************************************************** + * Setters + **************************************************/ + void + histo_sink_f_impl::set_frame_size(unsigned int frame_size) + { + gr::thread::scoped_lock guard(d_mutex); // hold mutex for duration of this function + d_frame_size = frame_size; + /* allocate a new sample array */ + delete [] d_samps; + d_samps = new float[d_frame_size]; + clear(); + } + + void + histo_sink_f_impl::set_num_bins(unsigned int num_bins) { + gr::thread::scoped_lock guard(d_mutex); // hold mutex for duration of this function + d_num_bins = num_bins; + /* allocate a new bin array */ + delete [] d_bins; + d_bins = new unsigned int[d_num_bins]; + clear(); + } + + } /* namespace wxgui */ +} /* namespace gr */ diff --git a/gr-wxgui/lib/histo_sink_f_impl.h b/gr-wxgui/lib/histo_sink_f_impl.h new file mode 100644 index 0000000000..98b0fe6706 --- /dev/null +++ b/gr-wxgui/lib/histo_sink_f_impl.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2013 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. + */ + +#ifndef INCLUDED_GR_HISTO_SINK_F_IMPL_H +#define INCLUDED_GR_HISTO_SINK_F_IMPL_H + +#include <wxgui/histo_sink_f.h> + +namespace gr { + namespace wxgui { + + class histo_sink_f_impl : public histo_sink_f + { + private: + gr_msg_queue_sptr d_msgq; + unsigned int d_num_bins; + unsigned int d_frame_size; + unsigned int d_sample_count; + unsigned int *d_bins; + float *d_samps; + gr::thread::mutex d_mutex; + + void send_frame(void); + void clear(void); + + public: + histo_sink_f_impl(gr_msg_queue_sptr msgq); + ~histo_sink_f_impl(void); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + unsigned int get_frame_size(void); + unsigned int get_num_bins(void); + + void set_frame_size(unsigned int frame_size); + void set_num_bins(unsigned int num_bins); + }; + + } /* namespace wxgui */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_HISTO_SINK_F_IMPL_H */ diff --git a/gr-wxgui/lib/oscope_guts.cc b/gr-wxgui/lib/oscope_guts.cc new file mode 100644 index 0000000000..3d1f085a6f --- /dev/null +++ b/gr-wxgui/lib/oscope_guts.cc @@ -0,0 +1,439 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003,2005,2013 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. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <wxgui/oscope_guts.h> +#include <stdexcept> +#include <stdio.h> +#include <algorithm> +#include <unistd.h> +#include <math.h> +#include <assert.h> + +namespace gr { + namespace wxgui { + + /* + * Bad performance if it's large, and flaky triggering if it's too small + */ + static const int OUTPUT_RECORD_SIZE = 1024; // Must be power of 2 + + /* + * For (slow-updated) STRIPCHART triggering, we make the record + * size larger, since we potentially want to be able to "see" + * hours of data. This works as long as the update rates to a + * STRIPCHART are low, which they generally are--that's rather + * what a stripchart is all about! + */ + static const int SCHART_MULT = 8; + + + static inline int + wrap_bi(int buffer_index, int mx) // wrap buffer index + { + return buffer_index & (mx - 1); + } + + static inline int + incr_bi(int buffer_index, int mx) // increment buffer index + { + return wrap_bi(buffer_index + 1, mx); + } + + static inline int + decr_bi(int buffer_index, int mx) // decrement buffer index + { + return wrap_bi(buffer_index - 1, mx); + } + + oscope_guts::oscope_guts(double sample_rate, gr_msg_queue_sptr msgq) + : d_nchannels(1), + d_msgq(msgq), + d_trigger_mode(TRIG_MODE_AUTO), + d_trigger_slope(TRIG_SLOPE_POS), + d_trigger_channel(0), + d_sample_rate(sample_rate), + d_update_rate(20), + d_trigger_level(0), + d_obi(0), + d_state(HOLD_OFF), + d_decimator_count(0), + d_decimator_count_init(1), + d_hold_off_count(0), + d_hold_off_count_init(OUTPUT_RECORD_SIZE/2-1), + d_pre_trigger_count(0), + d_post_trigger_count(0), + d_post_trigger_count_init(OUTPUT_RECORD_SIZE/2) + { + for(int i = 0; i < MAX_CHANNELS; i++) + d_buffer[i] = 0; + + for(int i = 0; i < MAX_CHANNELS; i++) { + d_buffer[i] = new float[OUTPUT_RECORD_SIZE*SCHART_MULT]; + for(int j = 0; j < OUTPUT_RECORD_SIZE*SCHART_MULT; j++) + d_buffer[i][j] = 0.0; + } + + // be sure buffer is full before first write + enter_hold_off(); + update_rate_or_decimation_changed(); + } + + oscope_guts::~oscope_guts() + { + for(int i = 0; i < MAX_CHANNELS; i++) + delete [] d_buffer[i]; + } + + // MANIPULATORS + void + oscope_guts::process_sample(const float *channel_data) + { + d_decimator_count--; + if(d_decimator_count > 0) + return; + + d_decimator_count = d_decimator_count_init; + + if(d_trigger_mode != TRIG_MODE_STRIPCHART) { + for(int i = 0; i < d_nchannels; i++) + d_buffer[i][d_obi] = channel_data[i]; // copy data into buffer + + switch(d_state) { + case HOLD_OFF: + d_hold_off_count--; + if(d_hold_off_count <= 0) + enter_look_for_trigger (); + break; + + case LOOK_FOR_TRIGGER: + if(found_trigger()) + enter_post_trigger(); + break; + + case POST_TRIGGER: + d_post_trigger_count--; + if(d_post_trigger_count <= 0) { + write_output_records(); + enter_hold_off(); + } + break; + + default: + assert(0); + } + + d_obi = incr_bi(d_obi, OUTPUT_RECORD_SIZE); + } + else { + for(int i = 0; i < d_nchannels; i++) { + for(int j = (OUTPUT_RECORD_SIZE*SCHART_MULT)-1; j > 0; j--) { + d_buffer[i][j] = d_buffer[i][j-1]; + } + d_buffer[i][0] = channel_data[i]; + } + d_trigger_off = 0; + write_output_records(); + } + } + + /* + * Functions called on state entry + */ + + void + oscope_guts::enter_hold_off() + { + d_state = HOLD_OFF; + d_hold_off_count = d_hold_off_count_init; + } + + void + oscope_guts::enter_look_for_trigger() + { + d_pre_trigger_count = 0; + d_state = LOOK_FOR_TRIGGER; + } + + void + oscope_guts::enter_post_trigger() + { + d_state = POST_TRIGGER; + d_post_trigger_count = d_post_trigger_count_init; + //ensure that the trigger offset is no more than than half a sample + if(d_trigger_off > .5) + d_trigger_off -= 1; + else + d_post_trigger_count--; + } + + // ---------------------------------------------------------------- + // returns true if trigger found + + bool + oscope_guts::found_trigger() + { + int mx = d_trigger_mode == TRIG_MODE_STRIPCHART ? OUTPUT_RECORD_SIZE*SCHART_MULT : + OUTPUT_RECORD_SIZE; + + float prev_sample = d_buffer[d_trigger_channel][decr_bi(d_obi, mx)]; + float new_sample = d_buffer[d_trigger_channel][d_obi]; + + switch(d_trigger_mode) { + + case TRIG_MODE_AUTO: //too many samples without a trigger + d_pre_trigger_count++; + if(d_pre_trigger_count > OUTPUT_RECORD_SIZE/2) + return true; + + case TRIG_MODE_NORM: //look for trigger + switch(d_trigger_slope) { + + case TRIG_SLOPE_POS: //trigger point in pos slope? + if(new_sample < d_trigger_level || prev_sample >= d_trigger_level) + return false; + break; + + case TRIG_SLOPE_NEG: //trigger point in neg slope? + if(new_sample > d_trigger_level || prev_sample <= d_trigger_level) + return false; + break; + } + + //calculate the trigger offset in % sample + d_trigger_off = (d_trigger_level - prev_sample)/(new_sample - prev_sample); + return true; + + case TRIG_MODE_FREE: //free run mode, always trigger + d_trigger_off = 0; + return true; + + default: + assert(0); + return false; + } + } + + // ---------------------------------------------------------------- + // write output records (duh!) + + void + oscope_guts::write_output_records() + { + int mx; + + mx = d_trigger_mode == TRIG_MODE_STRIPCHART ? + OUTPUT_RECORD_SIZE*SCHART_MULT : OUTPUT_RECORD_SIZE; + + // if the output queue if full, drop the data like its hot. + if(d_msgq->full_p()) + return; + // Build a message to hold the output records + gr_message_sptr msg = + gr_make_message(0, // msg type + d_nchannels, // arg1 for other side + mx, // arg2 for other side + ((d_nchannels * mx) + 1) * sizeof(float)); // sizeof payload + + float *out = (float *)msg->msg(); // get pointer to raw message buffer + + for(int ch = 0; ch < d_nchannels; ch++) { + // note that d_obi + 1 points at the oldest sample in the buffer + for(int i = 0; i < mx; i++) { + out[i] = d_buffer[ch][wrap_bi(d_obi + 1 + i, mx)]; + } + out += mx; + } + //Set the last sample as the trigger offset: + // The non gl scope sink will not look at this last sample. + // The gl scope sink will use this last sample as an offset. + out[0] = d_trigger_off; + d_msgq->handle(msg); // send the msg + } + + // ---------------------------------------------------------------- + + bool + oscope_guts::set_update_rate(double update_rate) + { + d_update_rate = std::min(std::max (1./10., update_rate), d_sample_rate); + update_rate_or_decimation_changed(); + return true; + } + + bool + oscope_guts::set_decimation_count(int decimator_count) + { + decimator_count = std::max(1, decimator_count); + d_decimator_count_init = decimator_count; + update_rate_or_decimation_changed(); + return true; + } + + bool + oscope_guts::set_sample_rate(double sample_rate) + { + d_sample_rate = sample_rate; + return set_update_rate(update_rate()); + } + + void + oscope_guts::update_rate_or_decimation_changed() + { + d_hold_off_count_init = + (int)rint(d_sample_rate / d_update_rate / d_decimator_count_init); + } + + bool + oscope_guts::set_trigger_channel(int channel) + { + if(channel >= 0 && channel < d_nchannels) { + d_trigger_channel = channel; + trigger_changed (); + return true; + } + + return false; + } + + bool + oscope_guts::set_trigger_mode(trigger_mode mode) + { + d_trigger_mode = mode; + trigger_changed(); + return true; + } + + bool + oscope_guts::set_trigger_slope(trigger_slope slope) + { + d_trigger_slope = slope; + trigger_changed(); + return true; + } + + bool + oscope_guts::set_trigger_level(double trigger_level) + { + d_trigger_level = trigger_level; + trigger_changed(); + return true; + } + + bool + oscope_guts::set_trigger_level_auto() + { + // find the level 1/2 way between the min and the max + + float min_v = d_buffer[d_trigger_channel][0]; + float max_v = d_buffer[d_trigger_channel][0]; + + for(int i = 1; i < OUTPUT_RECORD_SIZE; i++) { + min_v = std::min (min_v, d_buffer[d_trigger_channel][i]); + max_v = std::max (max_v, d_buffer[d_trigger_channel][i]); + } + return set_trigger_level((min_v + max_v) * 0.5); + } + + bool + oscope_guts::set_num_channels(int nchannels) + { + if(nchannels > 0 && nchannels <= MAX_CHANNELS) { + d_nchannels = nchannels; + return true; + } + return false; + } + + void + oscope_guts::trigger_changed() + { + enter_look_for_trigger(); + } + + // ACCESSORS + + int + oscope_guts::num_channels() const + { + return d_nchannels; + } + + double + oscope_guts::sample_rate() const + { + return d_sample_rate; + } + + double + oscope_guts::update_rate() const + { + return d_update_rate; + } + + int + oscope_guts::get_decimation_count() const + { + return d_decimator_count_init; + } + + int + oscope_guts::get_trigger_channel() const + { + return d_trigger_channel; + } + + trigger_mode + oscope_guts::get_trigger_mode() const + { + return d_trigger_mode; + } + + trigger_slope + oscope_guts::get_trigger_slope() const + { + return d_trigger_slope; + } + + double + oscope_guts::get_trigger_level() const + { + return d_trigger_level; + } + + int + oscope_guts::get_samples_per_output_record() const + { + int mx; + + mx = OUTPUT_RECORD_SIZE; + if(d_trigger_mode == TRIG_MODE_STRIPCHART) { + mx = OUTPUT_RECORD_SIZE*SCHART_MULT; + } + return mx; + } + + } /* namespace wxgui */ +} /* namespace gr */ diff --git a/gr-wxgui/lib/oscope_sink_f_impl.cc b/gr-wxgui/lib/oscope_sink_f_impl.cc new file mode 100644 index 0000000000..5e578cb8e3 --- /dev/null +++ b/gr-wxgui/lib/oscope_sink_f_impl.cc @@ -0,0 +1,83 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003-2005,2010,2013 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "oscope_sink_f_impl.h" +#include <wxgui/oscope_sink_x.h> +#include <wxgui/oscope_guts.h> +#include <gr_io_signature.h> + +namespace gr { + namespace wxgui { + + oscope_sink_f::sptr + oscope_sink_f::make(double sampling_rate, gr_msg_queue_sptr msgq) + { + return gnuradio::get_initial_sptr + (new oscope_sink_f_impl(sampling_rate, msgq)); + } + + oscope_sink_f_impl::oscope_sink_f_impl(double sampling_rate, gr_msg_queue_sptr msgq) + : oscope_sink_x("oscope_sink_f", + gr_make_io_signature(1, oscope_guts::MAX_CHANNELS, + sizeof(float)), + sampling_rate), + d_msgq(msgq) + { + d_guts = new oscope_guts(d_sampling_rate, d_msgq); + } + + oscope_sink_f_impl::~oscope_sink_f_impl() + { + } + + bool + oscope_sink_f_impl::check_topology(int ninputs, int noutputs) + { + return d_guts->set_num_channels(ninputs); + } + + int + oscope_sink_f_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + int ni = input_items.size(); + float tmp[oscope_guts::MAX_CHANNELS]; + + for(int i = 0; i < noutput_items; i++) { + + // FIXME for now, copy the data. Fix later if reqd + for(int ch = 0; ch < ni; ch++) + tmp[ch] = ((const float*)input_items[ch])[i]; + + d_guts->process_sample(tmp); + } + + return noutput_items; + } + + } /* namespace wxgui */ +} /* namespace gr */ diff --git a/gr-wxgui/lib/oscope_sink_f_impl.h b/gr-wxgui/lib/oscope_sink_f_impl.h new file mode 100644 index 0000000000..6ad28a885f --- /dev/null +++ b/gr-wxgui/lib/oscope_sink_f_impl.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003-2005,2013 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. + */ + +#ifndef INCLUDED_GR_OSCOPE_SINK_F_IMPL_H +#define INCLUDED_GR_OSCOPE_SINK_F_IMPL_H + +#include <wxgui/oscope_sink_f.h> + +namespace gr { + namespace wxgui { + + class oscope_sink_f_impl : public oscope_sink_f + { + private: + gr_msg_queue_sptr d_msgq; + + public: + oscope_sink_f_impl(double sampling_rate, gr_msg_queue_sptr msgq); + ~oscope_sink_f_impl(); + + bool check_topology(int ninputs, int noutputs); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace wxgui */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_OSCOPE_SINK_F_IMPL_H */ + diff --git a/gr-wxgui/lib/oscope_sink_x.cc b/gr-wxgui/lib/oscope_sink_x.cc new file mode 100644 index 0000000000..417442979c --- /dev/null +++ b/gr-wxgui/lib/oscope_sink_x.cc @@ -0,0 +1,161 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003,2004,2013 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <wxgui/oscope_sink_x.h> +#include <wxgui/oscope_guts.h> +#include <gr_io_signature.h> + +namespace gr { + namespace wxgui { + + oscope_sink_x::oscope_sink_x(const std::string name, + gr_io_signature_sptr input_sig, + double sampling_rate) + : gr_sync_block(name, input_sig, + gr_make_io_signature(0, 0, 0)), + d_sampling_rate(sampling_rate), d_guts(0) + { + } + + oscope_sink_x::~oscope_sink_x() + { + delete d_guts; + } + + // ---------------------------------------------------------------- + + bool + oscope_sink_x::set_update_rate(double update_rate) + { + return d_guts->set_update_rate(update_rate); + } + + bool + oscope_sink_x::set_decimation_count(int decimation_count) + { + return d_guts->set_decimation_count(decimation_count); + } + + bool + oscope_sink_x::set_trigger_channel(int channel) + { + return d_guts->set_trigger_channel(channel); + } + + bool + oscope_sink_x::set_trigger_mode(trigger_mode mode) + { + return d_guts->set_trigger_mode(mode); + } + + bool + oscope_sink_x::set_trigger_slope(trigger_slope slope) + { + return d_guts->set_trigger_slope(slope); + } + + bool + oscope_sink_x::set_trigger_level(double trigger_level) + { + return d_guts->set_trigger_level(trigger_level); + } + + bool + oscope_sink_x::set_trigger_level_auto() + { + return d_guts->set_trigger_level_auto(); + } + + bool + oscope_sink_x::set_sample_rate(double sample_rate) + { + return d_guts->set_sample_rate(sample_rate); + } + + bool + oscope_sink_x::set_num_channels(int nchannels) + { + return d_guts->set_num_channels(nchannels); + } + + // ACCESSORS + + int + oscope_sink_x::num_channels() const + { + return d_guts->num_channels(); + } + + double + oscope_sink_x::sample_rate() const + { + return d_guts->sample_rate(); + } + + double + oscope_sink_x::update_rate() const + { + return d_guts->update_rate(); + } + + int + oscope_sink_x::get_decimation_count() const + { + return d_guts->get_decimation_count(); + } + + int + oscope_sink_x::get_trigger_channel() const + { + return d_guts->get_trigger_channel(); + } + + trigger_mode + oscope_sink_x::get_trigger_mode() const + { + return d_guts->get_trigger_mode(); + } + + trigger_slope + oscope_sink_x::get_trigger_slope() const + { + return d_guts->get_trigger_slope(); + } + + double + oscope_sink_x::get_trigger_level() const + { + return d_guts->get_trigger_level(); + } + + int + oscope_sink_x::get_samples_per_output_record() const + { + return d_guts->get_samples_per_output_record(); + } + + } /* namespace wxgui */ +} /* namespace gr */ |