summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib/io
diff options
context:
space:
mode:
authorjcorgan2009-03-20 02:16:20 +0000
committerjcorgan2009-03-20 02:16:20 +0000
commitd9744799b7df6c09180778540bf55eb9dc84281b (patch)
tree311339459f5fae94417321c08b4d48710e03f30e /gnuradio-core/src/lib/io
parent88304ce16a97945d13510b5fdaefcc0f62462d9d (diff)
downloadgnuradio-d9744799b7df6c09180778540bf55eb9dc84281b.tar.gz
gnuradio-d9744799b7df6c09180778540bf55eb9dc84281b.tar.bz2
gnuradio-d9744799b7df6c09180778540bf55eb9dc84281b.zip
Merged r10463:10658 from jblum/gui_guts into trunk. Trunk passes distcheck.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@10660 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'gnuradio-core/src/lib/io')
-rw-r--r--gnuradio-core/src/lib/io/Makefile.am3
-rw-r--r--gnuradio-core/src/lib/io/gr_histo_sink.i39
-rw-r--r--gnuradio-core/src/lib/io/gr_histo_sink_f.cc169
-rw-r--r--gnuradio-core/src/lib/io/gr_histo_sink_f.h70
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_guts.cc170
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_guts.h16
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink.i8
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_f.cc10
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_f.h5
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_x.cc18
-rw-r--r--gnuradio-core/src/lib/io/gr_oscope_sink_x.h3
-rw-r--r--gnuradio-core/src/lib/io/gr_trigger_mode.h11
-rw-r--r--gnuradio-core/src/lib/io/io.i2
13 files changed, 420 insertions, 104 deletions
diff --git a/gnuradio-core/src/lib/io/Makefile.am b/gnuradio-core/src/lib/io/Makefile.am
index c307be133..4583a033c 100644
--- a/gnuradio-core/src/lib/io/Makefile.am
+++ b/gnuradio-core/src/lib/io/Makefile.am
@@ -33,6 +33,7 @@ libio_la_SOURCES = \
gr_file_source.cc \
gr_file_descriptor_sink.cc \
gr_file_descriptor_source.cc \
+ gr_histo_sink_f.cc \
gr_message_sink.cc \
gr_message_source.cc \
gr_oscope_guts.cc \
@@ -64,6 +65,7 @@ grinclude_HEADERS = \
gr_file_source.h \
gr_file_descriptor_sink.h \
gr_file_descriptor_source.h \
+ gr_histo_sink_f.h \
gr_message_sink.h \
gr_message_source.h \
gr_oscope_guts.h \
@@ -101,6 +103,7 @@ swiginclude_HEADERS = \
gr_file_source.i \
gr_file_descriptor_sink.i \
gr_file_descriptor_source.i \
+ gr_histo_sink.i \
gr_message_sink.i \
gr_message_source.i \
gr_oscope_sink.i \
diff --git a/gnuradio-core/src/lib/io/gr_histo_sink.i b/gnuradio-core/src/lib/io/gr_histo_sink.i
new file mode 100644
index 000000000..544d772fb
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_histo_sink.i
@@ -0,0 +1,39 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,histo_sink_f)
+
+gr_histo_sink_f_sptr gr_make_histo_sink_f (gr_msg_queue_sptr msgq);
+
+class gr_histo_sink_f : public gr_sync_block
+{
+public:
+ ~gr_histo_sink_f (void);
+
+ 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);
+
+};
diff --git a/gnuradio-core/src/lib/io/gr_histo_sink_f.cc b/gnuradio-core/src/lib/io/gr_histo_sink_f.cc
new file mode 100644
index 000000000..a923a7e45
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_histo_sink_f.cc
@@ -0,0 +1,169 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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 <gr_histo_sink_f.h>
+#include <gr_io_signature.h>
+
+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;
+}
+
+gr_histo_sink_f_sptr
+gr_make_histo_sink_f (gr_msg_queue_sptr msgq)
+{
+ return gr_histo_sink_f_sptr (new gr_histo_sink_f (msgq));
+}
+
+gr_histo_sink_f::gr_histo_sink_f (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)
+{
+ pthread_mutex_init(&d_mutex, 0);
+ //allocate arrays and clear
+ set_num_bins(d_num_bins);
+ set_frame_size(d_frame_size);
+}
+
+gr_histo_sink_f::~gr_histo_sink_f (void)
+{
+ pthread_mutex_destroy(&d_mutex);
+ delete [] d_samps;
+ delete [] d_bins;
+}
+
+int
+gr_histo_sink_f::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];
+ pthread_mutex_lock(&d_mutex);
+ 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();
+ }
+ }
+ pthread_mutex_unlock(&d_mutex);
+ return noutput_items;
+}
+
+void
+gr_histo_sink_f::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 = round((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
+gr_histo_sink_f::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
+gr_histo_sink_f::get_frame_size(void){
+ return d_frame_size;
+}
+
+unsigned int
+gr_histo_sink_f::get_num_bins(void){
+ return d_num_bins;
+}
+
+/**************************************************
+ * Setters
+ **************************************************/
+void
+gr_histo_sink_f::set_frame_size(unsigned int frame_size){
+ pthread_mutex_lock(&d_mutex);
+ d_frame_size = frame_size;
+ /* allocate a new sample array */
+ delete [] d_samps;
+ d_samps = new float[d_frame_size];
+ clear();
+ pthread_mutex_unlock(&d_mutex);
+}
+
+void
+gr_histo_sink_f::set_num_bins(unsigned int num_bins){
+ pthread_mutex_lock(&d_mutex);
+ d_num_bins = num_bins;
+ /* allocate a new bin array */
+ delete [] d_bins;
+ d_bins = new unsigned int[d_num_bins];
+ clear();
+ pthread_mutex_unlock(&d_mutex);
+}
diff --git a/gnuradio-core/src/lib/io/gr_histo_sink_f.h b/gnuradio-core/src/lib/io/gr_histo_sink_f.h
new file mode 100644
index 000000000..ae34d302d
--- /dev/null
+++ b/gnuradio-core/src/lib/io/gr_histo_sink_f.h
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 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_H
+#define INCLUDED_GR_HISTO_SINK_F_H
+
+#include <gr_sync_block.h>
+#include <gr_msg_queue.h>
+#include <pthread.h>
+
+class gr_histo_sink_f;
+typedef boost::shared_ptr<gr_histo_sink_f> gr_histo_sink_f_sptr;
+
+gr_histo_sink_f_sptr gr_make_histo_sink_f (gr_msg_queue_sptr msgq);
+
+/*!
+ * \brief Histogram module.
+ * \ingroup sink
+ */
+class gr_histo_sink_f : public gr_sync_block
+{
+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;
+ pthread_mutex_t d_mutex;
+
+ friend gr_histo_sink_f_sptr gr_make_histo_sink_f (gr_msg_queue_sptr msgq);
+ gr_histo_sink_f (gr_msg_queue_sptr msgq);
+ void send_frame(void);
+ void clear(void);
+
+public:
+ ~gr_histo_sink_f (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);
+
+};
+
+#endif /* INCLUDED_GR_HISTO_SINK_F_H */
diff --git a/gnuradio-core/src/lib/io/gr_oscope_guts.cc b/gnuradio-core/src/lib/io/gr_oscope_guts.cc
index 2272aa0f7..80f78240d 100644
--- a/gnuradio-core/src/lib/io/gr_oscope_guts.cc
+++ b/gnuradio-core/src/lib/io/gr_oscope_guts.cc
@@ -31,30 +31,31 @@
#include <math.h>
#include <assert.h>
-static const int OUTPUT_RECORD_SIZE = 2048; // must be power of 2
+static const int OUTPUT_RECORD_SIZE = 2048; // must be power of 2
static inline int
-wrap_bi (int buffer_index) // wrap buffer index
+wrap_bi (int buffer_index) // wrap buffer index
{
return buffer_index & (OUTPUT_RECORD_SIZE - 1);
}
static inline int
-incr_bi (int buffer_index) // increment buffer index
+incr_bi (int buffer_index) // increment buffer index
{
return wrap_bi (buffer_index + 1);
}
static inline int
-decr_bi (int buffer_index) // decrement buffer index
+decr_bi (int buffer_index) // decrement buffer index
{
return wrap_bi (buffer_index - 1);
}
-gr_oscope_guts::gr_oscope_guts (int nchannels, double sample_rate, gr_msg_queue_sptr msgq)
- : d_nchannels (nchannels),
+gr_oscope_guts::gr_oscope_guts (double sample_rate, gr_msg_queue_sptr msgq)
+ : d_nchannels (1),
d_msgq (msgq),
- d_trigger_mode (gr_TRIG_AUTO),
+ d_trigger_mode (gr_TRIG_MODE_AUTO),
+ d_trigger_slope (gr_TRIG_SLOPE_POS),
d_trigger_channel (0),
d_sample_rate (sample_rate),
d_update_rate (20),
@@ -65,19 +66,14 @@ gr_oscope_guts::gr_oscope_guts (int nchannels, double sample_rate, gr_msg_queue_
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),
- d_prev_sample (0)
+ d_post_trigger_count_init (OUTPUT_RECORD_SIZE/2)
{
- if (d_nchannels > MAX_CHANNELS){
- fprintf (stderr, "gr_oscope_guts: too many channels. MAX_CHANNELS = %d\n", MAX_CHANNELS);
- throw std::runtime_error ("too many channels");
- }
-
for (int i = 0; i < MAX_CHANNELS; i++)
d_buffer[i] = 0;
- for (int i = 0; i < d_nchannels; i++){
+ for (int i = 0; i < MAX_CHANNELS; i++){
d_buffer[i] = new float [OUTPUT_RECORD_SIZE];
for (int j = 0; j < OUTPUT_RECORD_SIZE; j++)
d_buffer[i][j] = 0.0;
@@ -109,10 +105,8 @@ gr_oscope_guts::process_sample (const float *channel_data)
d_decimator_count = d_decimator_count_init;
for (int i = 0; i < d_nchannels; i++)
- d_buffer[i][d_obi] = channel_data[i]; // copy data into buffer
+ d_buffer[i][d_obi] = channel_data[i]; // copy data into buffer
- int trigger = 0;
-
switch (d_state){
case HOLD_OFF:
d_hold_off_count--;
@@ -121,12 +115,8 @@ gr_oscope_guts::process_sample (const float *channel_data)
break;
case LOOK_FOR_TRIGGER:
- trigger = found_trigger (d_buffer[d_trigger_channel][d_obi]);
- if (trigger != 0){
+ if (found_trigger ())
enter_post_trigger ();
- if (trigger < 0) // previous sample was closer
- d_post_trigger_count--;
- }
break;
case POST_TRIGGER:
@@ -158,8 +148,8 @@ gr_oscope_guts::enter_hold_off ()
void
gr_oscope_guts::enter_look_for_trigger ()
{
+ d_pre_trigger_count = 0;
d_state = LOOK_FOR_TRIGGER;
- d_prev_sample = d_buffer[d_trigger_channel][d_obi];
}
void
@@ -167,48 +157,49 @@ gr_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 0 if no trigger found.
-// returns +1 if this sample is the trigger point
-// returns -1 if the previous sample is the trigger point
+// returns true if trigger found
-int
-gr_oscope_guts::found_trigger (float new_sample)
+bool
+gr_oscope_guts::found_trigger ()
{
- float prev_sample = d_prev_sample;
- d_prev_sample = new_sample;
- bool trig;
+ float prev_sample = d_buffer[d_trigger_channel][decr_bi(d_obi)];
+ float new_sample = d_buffer[d_trigger_channel][d_obi];
switch (d_trigger_mode){
- case gr_TRIG_AUTO: // always trigger
- return +1;
-
- case gr_TRIG_POS_SLOPE:
- trig = prev_sample < d_trigger_level && new_sample >= d_trigger_level;
- if (trig){
- if (fabs (prev_sample - d_trigger_level) < fabs (new_sample - d_trigger_level))
- return -1;
- else
- return +1;
- }
- return 0;
-
- case gr_TRIG_NEG_SLOPE:
- trig = prev_sample > d_trigger_level && new_sample <= d_trigger_level;
- if (trig){
- if (fabs (prev_sample - d_trigger_level) < fabs (new_sample - d_trigger_level))
- return -1;
- else
- return +1;
+ case gr_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 gr_TRIG_MODE_NORM: //look for trigger
+ switch (d_trigger_slope){
+
+ case gr_TRIG_SLOPE_POS: //trigger point in pos slope?
+ if (new_sample < d_trigger_level || prev_sample >= d_trigger_level) return false;
+ break;
+
+ case gr_TRIG_SLOPE_NEG: //trigger point in neg slope?
+ if (new_sample > d_trigger_level || prev_sample <= d_trigger_level) return false;
+ break;
}
- return 0;
+
+ //calculate the trigger offset in % sample
+ d_trigger_off = (d_trigger_level - prev_sample)/(new_sample - prev_sample);
+ return true;
+
+ case gr_TRIG_MODE_FREE: //free run mode, always trigger
+ d_trigger_off = 0;
+ return true;
default:
assert (0);
- return 0;
+ return false;
}
}
@@ -218,28 +209,30 @@ gr_oscope_guts::found_trigger (float new_sample)
void
gr_oscope_guts::write_output_records ()
{
- // if the output queue if full, drop the data on the ground.
+ // 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
+ // Build a message to hold the output records
gr_message_sptr msg =
- gr_make_message(0, // msg type
- d_nchannels, // arg1 for other side
- OUTPUT_RECORD_SIZE, // arg2 for other side
- d_nchannels * OUTPUT_RECORD_SIZE * sizeof(float)); // sizeof payload
+ gr_make_message(0, // msg type
+ d_nchannels, // arg1 for other side
+ OUTPUT_RECORD_SIZE, // arg2 for other side
+ ((d_nchannels * OUTPUT_RECORD_SIZE) + 1) * sizeof(float)); // sizeof payload
- float *out = (float *)msg->msg(); // get pointer to raw message buffer
+ 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 < OUTPUT_RECORD_SIZE; i++)
+ for (int i = 0; i < OUTPUT_RECORD_SIZE; i++){
out[i] = d_buffer[ch][wrap_bi(d_obi + 1 + i)];
-
+ }
out += OUTPUT_RECORD_SIZE;
}
-
- d_msgq->handle(msg); // send the msg
+ //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
}
// ----------------------------------------------------------------
@@ -291,15 +284,17 @@ gr_oscope_guts::set_trigger_channel (int channel)
bool
gr_oscope_guts::set_trigger_mode (gr_trigger_mode mode)
{
- switch (mode){
- case gr_TRIG_POS_SLOPE:
- case gr_TRIG_NEG_SLOPE:
- case gr_TRIG_AUTO:
- d_trigger_mode = mode;
- trigger_changed ();
- return true;
- }
- return false;
+ d_trigger_mode = mode;
+ trigger_changed ();
+ return true;
+}
+
+bool
+gr_oscope_guts::set_trigger_slope (gr_trigger_slope slope)
+{
+ d_trigger_slope = slope;
+ trigger_changed ();
+ return true;
}
bool
@@ -315,23 +310,30 @@ gr_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];
+ 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);
+}
- d_trigger_level = (min_v + max_v) * 0.5;
- trigger_changed ();
- return true;
+bool
+gr_oscope_guts::set_num_channels(int nchannels)
+{
+ if (nchannels > 0 && nchannels <= MAX_CHANNELS){
+ d_nchannels = nchannels;
+ return true;
+ }
+ return false;
}
+
void
gr_oscope_guts::trigger_changed ()
{
- // d_prev_sample = d_buffer[d_trigger_channel][decr_bi(d_obi)];
enter_look_for_trigger ();
}
@@ -373,6 +375,12 @@ gr_oscope_guts::get_trigger_mode () const
return d_trigger_mode;
}
+gr_trigger_slope
+gr_oscope_guts::get_trigger_slope () const
+{
+ return d_trigger_slope;
+}
+
double
gr_oscope_guts::get_trigger_level () const
{
diff --git a/gnuradio-core/src/lib/io/gr_oscope_guts.h b/gnuradio-core/src/lib/io/gr_oscope_guts.h
index ee3bbc31e..f39db62f6 100644
--- a/gnuradio-core/src/lib/io/gr_oscope_guts.h
+++ b/gnuradio-core/src/lib/io/gr_oscope_guts.h
@@ -41,13 +41,15 @@
*/
class gr_oscope_guts {
+public:
+ static const int MAX_CHANNELS = 8;
private:
- static const int MAX_CHANNELS = 16;
enum scope_state { HOLD_OFF, LOOK_FOR_TRIGGER, POST_TRIGGER };
int d_nchannels; // how many channels
gr_msg_queue_sptr d_msgq; // message queue we stuff output records into
- gr_trigger_mode d_trigger_mode;
+ gr_trigger_mode d_trigger_mode;
+ gr_trigger_slope d_trigger_slope;
int d_trigger_channel; // which channel to watch for trigger condition
double d_sample_rate; // input sample rate in Hz
double d_update_rate; // approx freq to produce an output record (Hz)
@@ -61,9 +63,10 @@ private:
int d_decimator_count_init;
int d_hold_off_count;
int d_hold_off_count_init;
+ int d_pre_trigger_count;
int d_post_trigger_count;
int d_post_trigger_count_init;
- float d_prev_sample; // used for trigger checking
+ float d_trigger_off; //%sample trigger is off
// NOT IMPLEMENTED
gr_oscope_guts (const gr_oscope_guts &rhs); // no copy constructor
@@ -71,7 +74,7 @@ private:
void trigger_changed ();
void update_rate_or_decimation_changed ();
- int found_trigger (float sample); // returns -1, 0, +1
+ bool found_trigger (); // returns true if found
void write_output_records ();
void enter_hold_off (); // called on state entry
@@ -80,7 +83,7 @@ private:
public:
// CREATORS
- gr_oscope_guts (int nchannels, double sample_rate, gr_msg_queue_sptr msgq);
+ gr_oscope_guts (double sample_rate, gr_msg_queue_sptr msgq);
~gr_oscope_guts ();
// MANIPULATORS
@@ -95,9 +98,11 @@ public:
bool set_decimation_count (int decimation_count);
bool set_trigger_channel (int channel);
bool set_trigger_mode (gr_trigger_mode mode);
+ bool set_trigger_slope (gr_trigger_slope slope);
bool set_trigger_level (double trigger_level);
bool set_trigger_level_auto (); // set to 50% level
bool set_sample_rate(double sample_rate);
+ bool set_num_channels(int nchannels);
// ACCESSORS
@@ -107,6 +112,7 @@ public:
int get_decimation_count () const;
int get_trigger_channel () const;
gr_trigger_mode get_trigger_mode () const;
+ gr_trigger_slope get_trigger_slope () const;
double get_trigger_level () const;
// # of samples written to each output record.
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink.i b/gnuradio-core/src/lib/io/gr_oscope_sink.i
index 7802dac8a..9d634193b 100644
--- a/gnuradio-core/src/lib/io/gr_oscope_sink.i
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink.i
@@ -20,11 +20,7 @@
* Boston, MA 02110-1301, USA.
*/
-enum gr_trigger_mode {
- gr_TRIG_AUTO, // auto trigger (on anything)
- gr_TRIG_POS_SLOPE, // trigger on positive slope across trigger level
- gr_TRIG_NEG_SLOPE // trigger on negative slope across trigger level
-};
+%include gr_trigger_mode.h
// GR_SWIG_BLOCK_MAGIC(gr,oscope_sink_x)
@@ -43,6 +39,7 @@ class gr_oscope_sink_x : public gr_sync_block
bool set_decimation_count (int decimation_count);
bool set_trigger_channel (int channel);
bool set_trigger_mode (gr_trigger_mode mode);
+ bool set_trigger_slope (gr_trigger_slope slope);
bool set_trigger_level (double trigger_level);
bool set_trigger_level_auto (); // set to 50% level
bool set_sample_rate(double sample_rate);
@@ -54,6 +51,7 @@ class gr_oscope_sink_x : public gr_sync_block
int get_decimation_count () const;
int get_trigger_channel () const;
gr_trigger_mode get_trigger_mode () const;
+ gr_trigger_slope get_trigger_slope () const;
double get_trigger_level () const;
// # of samples written to each output record.
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_f.cc b/gnuradio-core/src/lib/io/gr_oscope_sink_f.cc
index 5e0e30660..cb401699e 100644
--- a/gnuradio-core/src/lib/io/gr_oscope_sink_f.cc
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_f.cc
@@ -38,20 +38,18 @@ gr_make_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq)
gr_oscope_sink_f::gr_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq)
: gr_oscope_sink_x ("oscope_sink_f",
- gr_make_io_signature (1, MAX_CHANNELS, sizeof (float)),
+ gr_make_io_signature (1, gr_oscope_guts::MAX_CHANNELS, sizeof (float)),
sampling_rate),
d_msgq(msgq)
{
+ d_guts = new gr_oscope_guts (d_sampling_rate, d_msgq);
}
bool
gr_oscope_sink_f::check_topology (int ninputs, int noutputs)
{
- delete d_guts;
- d_guts = 0;
- d_guts = new gr_oscope_guts (ninputs, d_sampling_rate, d_msgq);
- return true;
+ return d_guts->set_num_channels(ninputs);
}
@@ -65,7 +63,7 @@ gr_oscope_sink_f::work (int noutput_items,
gr_vector_void_star &output_items)
{
int ni = input_items.size ();
- float tmp[MAX_CHANNELS];
+ float tmp[gr_oscope_guts::MAX_CHANNELS];
for (int i = 0; i < noutput_items; i++){
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_f.h b/gnuradio-core/src/lib/io/gr_oscope_sink_f.h
index 620aac374..22d145c54 100644
--- a/gnuradio-core/src/lib/io/gr_oscope_sink_f.h
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_f.h
@@ -36,13 +36,10 @@ gr_oscope_sink_f_sptr gr_make_oscope_sink_f (double sampling_rate, gr_msg_queue_
* \brief Building block for python oscilloscope module.
* \ingroup sink
*
- * Accepts 1 to 16 float streams.
+ * Accepts multiple float streams.
*/
class gr_oscope_sink_f : public gr_oscope_sink_x
{
-public:
- static const int MAX_CHANNELS = 16;
-
private:
friend gr_oscope_sink_f_sptr
gr_make_oscope_sink_f (double sampling_rate, gr_msg_queue_sptr msgq);
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_x.cc b/gnuradio-core/src/lib/io/gr_oscope_sink_x.cc
index f2c2d4371..2bbd57463 100644
--- a/gnuradio-core/src/lib/io/gr_oscope_sink_x.cc
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_x.cc
@@ -69,6 +69,12 @@ gr_oscope_sink_x::set_trigger_mode (gr_trigger_mode mode)
}
bool
+gr_oscope_sink_x::set_trigger_slope (gr_trigger_slope slope)
+{
+ return d_guts->set_trigger_slope (slope);
+}
+
+bool
gr_oscope_sink_x::set_trigger_level (double trigger_level)
{
return d_guts->set_trigger_level (trigger_level);
@@ -87,6 +93,12 @@ gr_oscope_sink_x::set_sample_rate (double sample_rate)
return d_guts->set_sample_rate (sample_rate);
}
+bool
+gr_oscope_sink_x::set_num_channels (int nchannels)
+{
+ return d_guts->set_num_channels (nchannels);
+}
+
// ACCESSORS
int
@@ -125,6 +137,12 @@ gr_oscope_sink_x::get_trigger_mode () const
return d_guts->get_trigger_mode ();
}
+gr_trigger_slope
+gr_oscope_sink_x::get_trigger_slope () const
+{
+ return d_guts->get_trigger_slope ();
+}
+
double
gr_oscope_sink_x::get_trigger_level () const
{
diff --git a/gnuradio-core/src/lib/io/gr_oscope_sink_x.h b/gnuradio-core/src/lib/io/gr_oscope_sink_x.h
index 6dc0d6335..408979eb6 100644
--- a/gnuradio-core/src/lib/io/gr_oscope_sink_x.h
+++ b/gnuradio-core/src/lib/io/gr_oscope_sink_x.h
@@ -51,9 +51,11 @@ public:
bool set_decimation_count (int decimation_count);
bool set_trigger_channel (int channel);
bool set_trigger_mode (gr_trigger_mode mode);
+ bool set_trigger_slope (gr_trigger_slope slope);
bool set_trigger_level (double trigger_level);
bool set_trigger_level_auto (); // set to 50% level
bool set_sample_rate(double sample_rate);
+ bool set_num_channels (int nchannels);
// ACCESSORS
@@ -63,6 +65,7 @@ public:
int get_decimation_count () const;
int get_trigger_channel () const;
gr_trigger_mode get_trigger_mode () const;
+ gr_trigger_slope get_trigger_slope () const;
double get_trigger_level () const;
// # of samples written to each output record.
diff --git a/gnuradio-core/src/lib/io/gr_trigger_mode.h b/gnuradio-core/src/lib/io/gr_trigger_mode.h
index 18d49ecfd..63f6b1c98 100644
--- a/gnuradio-core/src/lib/io/gr_trigger_mode.h
+++ b/gnuradio-core/src/lib/io/gr_trigger_mode.h
@@ -24,9 +24,14 @@
#define INCLUDED_GR_TRIGGER_MODE_H
enum gr_trigger_mode {
- gr_TRIG_AUTO, // auto trigger (on anything)
- gr_TRIG_POS_SLOPE, // trigger on positive slope across trigger level
- gr_TRIG_NEG_SLOPE // trigger on negative slope across trigger level
+ gr_TRIG_MODE_FREE,
+ gr_TRIG_MODE_AUTO,
+ gr_TRIG_MODE_NORM,
+};
+
+enum gr_trigger_slope {
+ gr_TRIG_SLOPE_POS,
+ gr_TRIG_SLOPE_NEG,
};
#endif /* INCLUDED_GR_TRIGGER_MODE_H */
diff --git a/gnuradio-core/src/lib/io/io.i b/gnuradio-core/src/lib/io/io.i
index ed7feb49d..3538942ca 100644
--- a/gnuradio-core/src/lib/io/io.i
+++ b/gnuradio-core/src/lib/io/io.i
@@ -30,6 +30,7 @@
#include <gr_file_source.h>
#include <gr_file_descriptor_sink.h>
#include <gr_file_descriptor_source.h>
+#include <gr_histo_sink_f.h>
#include <microtune_4702_eval_board.h>
#include <microtune_4937_eval_board.h>
#include <sdr_1000.h>
@@ -50,6 +51,7 @@
%include "gr_file_source.i"
%include "gr_file_descriptor_sink.i"
%include "gr_file_descriptor_source.i"
+%include "gr_histo_sink.i"
%include "microtune_xxxx_eval_board.i"
%include "microtune_4702_eval_board.i"
%include "microtune_4937_eval_board.i"