diff options
author | Ruben Undheim <ruben.undheim@gmail.com> | 2018-09-09 08:16:32 +0200 |
---|---|---|
committer | Ruben Undheim <ruben.undheim@gmail.com> | 2018-09-09 08:16:32 +0200 |
commit | e7586d5cbd6ce764a8d87a6440f78202b5f26e9a (patch) | |
tree | 7d2d89f3640c1cdd17090de7c6db57bff0d096c9 /lib | |
parent | 185d516406c10e9c8efc7870606ae0d71bc434e3 (diff) |
Imported 0.2.1+20180909git0a11294
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/xrun_monitor_cc_impl.cc | 246 | ||||
-rw-r--r-- | lib/xrun_monitor_cc_impl.h | 62 |
3 files changed, 310 insertions, 1 deletions
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index c7707e0..e7bef4e 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -65,7 +65,8 @@ list(APPEND dab_sources fec/init_rs_char.c valve_ff_impl.cc peak_detector_fb_impl.cc - control_stream_to_tag_cc_impl.cc ) + control_stream_to_tag_cc_impl.cc + xrun_monitor_cc_impl.cc ) set(dab_sources "${dab_sources}" PARENT_SCOPE) diff --git a/lib/xrun_monitor_cc_impl.cc b/lib/xrun_monitor_cc_impl.cc new file mode 100644 index 0000000..dc66fd8 --- /dev/null +++ b/lib/xrun_monitor_cc_impl.cc @@ -0,0 +1,246 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 Ruben Undheim <ruben.undheim@gmail.com> + * + * This 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. + * + * This software 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 this software; 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 <gnuradio/io_signature.h> +#include "xrun_monitor_cc_impl.h" + +namespace gr { + namespace dab { + + xrun_monitor_cc::sptr + xrun_monitor_cc::make(int length) + { + return gnuradio::get_initial_sptr + (new xrun_monitor_cc_impl(length)); + } + + /* + * The private constructor + */ + xrun_monitor_cc_impl::xrun_monitor_cc_impl(int length) + : gr::block("xrun_monitor_cc", + gr::io_signature::make(1, 1, sizeof(gr_complex)), + gr::io_signature::make(1, 1, sizeof(gr_complex))) + { + d_n = 0; + d_produce_per = 100; + d_write_index = 0; + d_read_index = 0; + d_length = length; + d_buffer = new gr_complex[d_length]; + d_first = true; + d_starting = true; + d_drop_when_full = false; + } + + /* + * Our virtual destructor. + */ + xrun_monitor_cc_impl::~xrun_monitor_cc_impl() + { + delete(d_buffer); + } + + void + xrun_monitor_cc_impl::set_drop_when_full(bool val) + { + d_drop_when_full = val; + } + + void + xrun_monitor_cc_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) + { + if (noutput_items >= 10) { + ninput_items_required[0] = noutput_items; + } + else { + int current_fill; + if (d_read_index < d_write_index) + current_fill = d_write_index - d_read_index; + else if (d_read_index == d_write_index) + current_fill = 0; + else + current_fill = d_length - d_read_index + d_write_index; + + float fill_percentage = (((float)current_fill)/((float)d_length))*100; + if(fill_percentage > 30 || d_starting) { + ninput_items_required[0] = 0; + } + else { + ninput_items_required[0] = noutput_items; + d_starting = true; + printf("Fill fell below 30%% Starting again\n"); + } + } + + } + + int + xrun_monitor_cc_impl::general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = NULL; + if (input_items.size() > 0) + in = (const gr_complex *) input_items[0]; + gr_complex *out = (gr_complex *) output_items[0]; + + // Do <+signal processing+> + int zeros_to_produce = 0; + int current_fill; + if (d_read_index < d_write_index) + current_fill = d_write_index - d_read_index; + else if (d_read_index == d_write_index) + current_fill = 0; + else { + current_fill = d_length - d_read_index + d_write_index; + } + float fill_percentage; + fill_percentage = (((float)current_fill)/((float)d_length))*100; + if (d_starting && fill_percentage < 50) { + zeros_to_produce = noutput_items; + noutput_items = 0; + } + else { + d_starting = false; + } + + + int produced = 0; + int consumed = 0; + int remaining; + int to_produce_here; + int toread; + int outpos = 0; + + if (d_read_index < d_write_index) { + toread = d_write_index - d_read_index; + to_produce_here = std::min(toread, noutput_items); + memcpy(out, d_buffer + d_read_index, sizeof(gr_complex) * to_produce_here); + d_read_index += to_produce_here; + remaining = noutput_items - to_produce_here; + outpos = to_produce_here; + produced += to_produce_here; + } + else if (d_read_index == d_write_index){ + remaining = noutput_items; + outpos = 0; + } + else { + toread = d_length - d_read_index; + to_produce_here = std::min(toread, noutput_items); + memcpy(out, d_buffer + d_read_index, sizeof(gr_complex) * to_produce_here); + remaining = noutput_items - to_produce_here; + produced += to_produce_here; + if (remaining > 0) { + int to_produce_here2 = std::min(d_write_index, remaining); + memcpy(out+to_produce_here, d_buffer, sizeof(gr_complex) * to_produce_here2); + d_read_index = to_produce_here2; + remaining = remaining - to_produce_here2; + outpos = to_produce_here + to_produce_here2; + produced += to_produce_here2; + } + else if (remaining == 0) { + if ((d_read_index + to_produce_here ) < d_length) + d_read_index += to_produce_here; + else + d_read_index = 0; + outpos = to_produce_here; + } + else { + outpos = to_produce_here; + d_read_index += to_produce_here; + } + } + + int to_produce = std::min(ninput_items[0], remaining); + memcpy(out+outpos, in, sizeof(gr_complex) * to_produce); + produced += to_produce; + consumed += to_produce; + //if ((to_produce_here + to_produce) <= d_length) { + //} + //else { + // memcpy(out+to_produce_here, in, sizeof(gr_complex) * (d_length - (to_produce_here + to_produce))); + // memcpy(out+to_produce_here, in, sizeof(gr_complex) * (d_length - (to_produce_here + to_produce))); + //} + int tosave = ninput_items[0] - (to_produce); + + if (d_read_index < d_write_index) + current_fill = d_write_index - d_read_index; + else if (d_read_index == d_write_index) + current_fill = 0; + else { + current_fill = d_length - d_read_index + d_write_index; + } + + if(tosave >= (d_length-current_fill)) { + printf("Buffer full!\n"); + tosave = d_length - current_fill - 1; + } + + if ((d_write_index + tosave) < d_length) { + memcpy(d_buffer + d_write_index, in + to_produce, sizeof(gr_complex) * tosave); + d_write_index = d_write_index + tosave; + } + else { + memcpy(d_buffer + d_write_index, in + to_produce, sizeof(gr_complex) * (d_length - d_write_index)); + memcpy(d_buffer, in + to_produce + (d_length - d_write_index), sizeof(gr_complex) * (tosave - (d_length - d_write_index))); + d_write_index = tosave - (d_length - d_write_index); + } + consumed += tosave; + + d_n += noutput_items; + + + if (d_read_index < d_write_index) + current_fill = d_write_index - d_read_index; + else if (d_read_index == d_write_index) + current_fill = 0; + else { + current_fill = d_length - d_read_index + d_write_index; + } + + if (d_n > 10000) { + //printf("ninput_items: %d, noutput_items: %d\n", ninput_items[0], noutput_items); + printf("Fill: %f %\n", (((float)current_fill)/((float)d_length))*100); + d_n = 0; + } + + for(int i=0;i<zeros_to_produce;i++) { + out[i] = 0; + produced++; + } + + if (d_drop_when_full) + consume_each(ninput_items[0]); + else + consume_each(consumed); + // Tell runtime system how many output items we produced. + return produced; + } + + } /* namespace dab */ +} /* namespace gr */ + diff --git a/lib/xrun_monitor_cc_impl.h b/lib/xrun_monitor_cc_impl.h new file mode 100644 index 0000000..5ece0fa --- /dev/null +++ b/lib/xrun_monitor_cc_impl.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2018 Ruben Undheim <ruben.undheim@gmail.com> + * + * This 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. + * + * This software 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 this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_CAPTURE_TOOLS_XRUN_MONITOR_CC_IMPL_H +#define INCLUDED_CAPTURE_TOOLS_XRUN_MONITOR_CC_IMPL_H + +#include <grdab/xrun_monitor_cc.h> + +namespace gr { + namespace dab { + + class xrun_monitor_cc_impl : public xrun_monitor_cc + { + private: + // Nothing to declare in this block. + int d_n; + int d_produce_per; + gr_complex *d_buffer; + int d_write_index; + int d_read_index; + int d_length; + bool d_first; + bool d_starting; + bool d_drop_when_full; + + public: + xrun_monitor_cc_impl(int length); + ~xrun_monitor_cc_impl(); + + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + + int general_work(int noutput_items, + gr_vector_int &ninpnut_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + void set_drop_when_full(bool val); + + }; + + } // namespace dab +} // namespace gr + +#endif /* INCLUDED_CAPTURE_TOOLS_XRUN_MONITOR_CC_IMPL_H */ + |