Hi there,

I have modified the delay block of baz to control it from a clock of
seconds.
But I do not know if this is the best implementation... :S


Greetings.
/* -*- c++ -*- */
/*
 * Copyright 2007 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-baz by Balint Seeber (http://spench.net/contact)
 * Information, documentation & samples: http://wiki.spench.net/wiki/gr-baz
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <baz_delay.h>
#include <gnuradio/io_signature.h>
#include <string.h>
#include <math.h>

using namespace std;

baz_delay_sptr
baz_make_delay (size_t itemsize, int delay)
{
  return baz_delay_sptr (new baz_delay (itemsize, delay));
}

baz_delay::baz_delay (size_t itemsize, int delay)
	: gr::sync_block ("variable_delay",
		gr::io_signature::make (2, 2, itemsize),
		gr::io_signature::make (1, 1, itemsize))
	, d_itemsize(itemsize)
	, d_delay(delay)
	, d_buffer(NULL)
	, d_buffer_length(delay * 2)
	, d_zero(delay)
	, d_buffer_pos(0)
	, d_buffer_use(0)
{
  if (d_buffer_length > 0)
	d_buffer = (unsigned char*)malloc(d_buffer_length * 2 * itemsize);
}

void baz_delay::set_delay(int delay)
{	
	if (delay < 0)
		return;
	if (delay == d_delay)
		return;
	boost::mutex::scoped_lock guard(d_mutex);
  
	if (delay > d_delay)
	{
		if (delay > d_buffer_length)
		{
			int new_size = std::max(delay * 2, d_buffer_length * 2);	// (delay + 1) & ~1
			d_buffer = (unsigned char*)realloc(d_buffer, new_size * d_itemsize);
			int diff = ((d_buffer_pos + d_buffer_use) - d_buffer_length);
			if (diff > 0)
				memcpy(d_buffer + (d_itemsize * d_buffer_length), d_buffer, (d_itemsize * diff));
			d_buffer_length = new_size;
		}
	
		int diff = delay - d_delay;
		d_zero += diff;
	}
	else
	{
		int diff = d_delay - delay;
		int zero_diff = max(0, d_zero - diff);
		d_zero -= zero_diff;
		diff -= zero_diff;
		{
			int buffer_diff = min(d_buffer_use, diff);
			d_buffer_pos = (d_buffer_pos + buffer_diff) % d_buffer_length;
			d_buffer_use -= buffer_diff;
		}
	}
  
	d_delay = delay;
}

int
baz_delay::work (int noutput_items,
	gr_vector_const_void_star &input_items,
	gr_vector_void_star &output_items)
{
	const int *inDelay = (const int *) input_items[1];
  	set_delay(inDelay[1]);

	assert(input_items.size()-1 == output_items.size());

	boost::mutex::scoped_lock guard(d_mutex);
  
	int zero = min(d_zero, noutput_items);
	int residual = min(zero + d_buffer_use, noutput_items);
	int to_copy_offset = noutput_items - residual;
	int to_copy_length = noutput_items - to_copy_offset;
	assert(to_copy_offset + to_copy_length == noutput_items);
  
	if ((d_buffer_use + to_copy_length) > d_buffer_length)
	{
		int new_size = max((d_buffer_use + to_copy_length) + (((d_buffer_use + to_copy_length) % 2) ? 1 : 0), d_buffer_length * 2);
		d_buffer = (unsigned char*)realloc(d_buffer, new_size * d_itemsize);
		int diff = ((d_buffer_pos + d_buffer_use) - d_buffer_length);
		if (diff > 0)
			memcpy(d_buffer + (d_itemsize * d_buffer_length), d_buffer, (d_itemsize * diff));
		d_buffer_length = new_size;
	}
  
	int buffer_free_start = (d_buffer_length ? ((d_buffer_pos + d_buffer_use) % d_buffer_length) : 0);
	int diff = noutput_items - zero;
  
	int to_copy_length1 = to_copy_length;
	int to_copy_length2 = 0;
	if ((d_buffer_length) && (((buffer_free_start + to_copy_length) % d_buffer_length) < buffer_free_start))
	{
		to_copy_length1 = d_buffer_length - buffer_free_start;
		to_copy_length2 = to_copy_length - to_copy_length1;
	}

	int buf_diff = min(diff, d_buffer_use);
	int i1 = min(d_buffer_length - d_buffer_pos, buf_diff);
	int i2 = buf_diff - i1;
	assert(i1 + i2 == buf_diff);

	for (size_t i = 0; i < 1; i++)	// FIXME: Create multiple buffers for each stream!
	{
		const char* iptr = (const char *) input_items[i];
		char* optr = (char *) output_items[i];
	
		if ((d_delay == 0) ||
			(d_buffer == NULL) || (d_buffer_length == 0))	// Just in case
		{
			memcpy(optr, iptr, noutput_items * d_itemsize);
			continue;
		}
		if (to_copy_length)
		{
			unsigned char* obuf = d_buffer + (buffer_free_start * d_itemsize);
			memcpy(obuf, iptr + (d_itemsize * to_copy_offset), (d_itemsize * to_copy_length1));
			if (to_copy_length2)
				memcpy(d_buffer, iptr + (d_itemsize * (to_copy_offset + to_copy_length1)), (d_itemsize * to_copy_length2));
			d_buffer_use += to_copy_length;
		}
	
		if (zero)
		{
			if (d_buffer_use)
			{
				const unsigned char* z = d_buffer + (d_buffer_pos * d_itemsize);
				for (int i = 0; i < zero; ++i)
					memcpy(optr + (i * d_itemsize), z, d_itemsize);
			}
			else
				memset(optr, 0x00, d_itemsize * zero);
			optr += d_itemsize * zero;
		}
		if (zero == noutput_items)
		{
			continue;
		}
	
		if (buf_diff)
		{
			memcpy(optr, d_buffer + (d_buffer_pos * d_itemsize), i1 * d_itemsize);
			if (i2)
				emcpy(optr + (i1 * d_itemsize), d_buffer, i2 * d_itemsize);
			optr += buf_diff * d_itemsize;
			d_buffer_pos = (d_buffer_pos + buf_diff) % d_buffer_length;
			d_buffer_use -= buf_diff;
		}
		if ((zero + buf_diff) == noutput_items)
		{
			continue;
		}
		int rest = (noutput_items - (zero + buf_diff));
		memcpy(optr, iptr, rest * d_itemsize);
	}

	d_zero -= zero;
	return noutput_items;
}
/* -*- c++ -*- */
/*
 * Copyright 2007,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.
 */

/*
 * gr-baz by Balint Seeber (http://spench.net/contact)
 * Information, documentation & samples: http://wiki.spench.net/wiki/gr-baz
 */

#ifndef INCLUDED_BAZ_DELAY_H
#define INCLUDED_BAZ_DELAY_H

#include <gnuradio/sync_block.h>
#include <boost/thread.hpp>

class BAZ_API baz_delay;
typedef boost::shared_ptr<baz_delay> baz_delay_sptr;

BAZ_API baz_delay_sptr baz_make_delay (size_t itemsize, int delay);

/*!
 * \brief delay the input by a certain number of samples
 * \ingroup misc_blk
 */
class BAZ_API baz_delay : public gr::sync_block
{
	friend BAZ_API baz_delay_sptr baz_make_delay (size_t itemsize, int delay);

	baz_delay (size_t itemsize, int delay);

	boost::mutex	d_mutex;
	size_t d_itemsize;
	int d_delay;
	unsigned char* d_buffer;
	int d_buffer_length;
	int d_zero;
	int d_buffer_pos;
	int d_buffer_use;

	public:
		int delay () const { return d_delay; }
		void set_delay (int delay);

		int work (int noutput_items,
			gr_vector_const_void_star &input_items,
			gr_vector_void_star &output_items);
};

#endif
/* -*- c++ -*- */
/*
 * Copyright 2014 <+YOU OR YOUR COMPANY+>.
 *
 * 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 "reloj_ff_impl.h"

namespace gr {
  namespace howto {

    reloj_ff::sptr
    reloj_ff::make(int tasa, int precision)
    {
      return gnuradio::get_initial_sptr
        (new reloj_ff_impl(tasa, precision));
    }

    /*
     * The private constructor
     */
    reloj_ff_impl::reloj_ff_impl(int tasa, int precision)
      : gr::block("reloj_ff",
		       gr::io_signature::make(1,1,sizeof(float)),
		       gr::io_signature::make(1,1, sizeof(float)))
    {
        inicios=precision;

        reloj_pc_anteriors=0;
        reloj_pc_anteriorm=0;

        count=0;
    }

    /*
     * Our virtual destructor.
     */
    reloj_ff_impl::~reloj_ff_impl()
    {
    }

    void
    reloj_ff_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required)
    {
        ninput_items_required[0] = noutput_items;
    }

    int
    reloj_ff_impl::general_work (int noutput_items,
                       gr_vector_int &ninput_items,
                       gr_vector_const_void_star &input_items,
                       gr_vector_void_star &output_items)
    {
		float *outseconds = (float*)output_items[0];

        for(int i=0;i<noutput_items;++i){

            time_t now;
            struct tm seg;

            time(&now);
            seg = *localtime(&now);
            reloj_pc_actuals= seg.tm_sec;

            if( (reloj_pc_actuals!=reloj_pc_anteriors) && (reloj_pc_anteriors!=0) ){
                inicios=inicios+1;
            }

            outseconds[i] = inicios;
            reloj_pc_anteriors=reloj_pc_actuals;
        }

        // Tell runtime system how many input items we consumed on
        // each input stream.
        consume_each (ninput_items[0]);

        // Tell runtime system how many output items we produced.
        return noutput_items;
    }

  } /* namespace howto */
} /* namespace gr */



/* -*- c++ -*- */
/*
 * Copyright 2014 <+YOU OR YOUR COMPANY+>.
 *
 * 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_HOWTO_RELOJ_FF_IMPL_H
#define INCLUDED_HOWTO_RELOJ_FF_IMPL_H

#include <howto/reloj_ff.h>
#include "time.h"


namespace gr {
  namespace howto {

    class reloj_ff_impl : public reloj_ff
    {
     private:
      // Nothing to declare in this block.

     public:
      reloj_ff_impl(int tasa, int precision);
      ~reloj_ff_impl();
        time_t timer;

        int inicios;

        int reloj_pc_anteriors;
        int reloj_pc_actuals;



      // Where all the action really happens
      void forecast (int noutput_items, gr_vector_int &ninput_items_required);

      int general_work(int noutput_items,
		       gr_vector_int &ninput_items,
		       gr_vector_const_void_star &input_items,
		       gr_vector_void_star &output_items);
    };

  } // namespace howto
} // namespace gr

#endif /* INCLUDED_HOWTO_RELOJ_FF_IMPL_H */

_______________________________________________
Discuss-gnuradio mailing list
Discuss-gnuradio@gnu.org
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Reply via email to