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
[email protected]
https://lists.gnu.org/mailman/listinfo/discuss-gnuradio