Abandon idea of P25 decoder being a sink. This means subclassing gr_block instead of gr_sync_block, some name changes and allowing for audio output from the block.

git-svn-id: http://op25.osmocom.org/svn/trunk@91 65a5c917-d112-43f1-993d-58c26a4786be
This commit is contained in:
stevie 2008-09-09 09:03:37 +00:00
parent e816a8c913
commit ead89bda24
6 changed files with 63 additions and 47 deletions

View File

@ -1 +1,3 @@
This package implements an APCO P25 decoder as a GNU Radio signal sink.
This package implements an APCO P25 decoder as a GNU Radio signal
processing block. It is intended to be used with the Radio Rausch
4-Level FSK demodulator.

View File

@ -21,7 +21,7 @@
include $(top_srcdir)/Makefile.common
# Install this stuff so that it ends up as the op25.decoder_f
# Install this stuff so that it ends up as the op25.decoder_ff
# module. This usually ends up at:
# ${prefix}/lib/python${python_version}/site-packages/gnuradio
@ -68,7 +68,7 @@ _op25_la_SOURCES = \
packet.cc \
terminator.cc \
op25.cc \
op25_decoder_f.cc
op25_decoder_ff.cc
# magic flags
_op25_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version
@ -84,7 +84,7 @@ op25.cc op25.py: $(LOCAL_IFILES) $(ALL_IFILES)
# These headers get installed in ${prefix}/include/gnuradio
grinclude_HEADERS = \
op25_decoder_f.h
op25_decoder_ff.h
# These swig headers get installed in ${prefix}/include/gnuradio/swig
swiginclude_HEADERS = \

View File

@ -7,7 +7,7 @@
%{
#include "gnuradio_swig_bug_workaround.h"
#include "op25_decoder_f.h"
#include "op25_decoder_ff.h"
#include <stdexcept>
%}
@ -16,20 +16,20 @@
* Second arg is the name of the class minus the prefix.
*
* This does some behind-the-scenes magic so we can access
* op25_decoder_f from python as op25.decoder_f
* op25_decoder_ff from python as op25.decoder_ff.
*/
GR_SWIG_BLOCK_MAGIC(op25,decoder_f);
GR_SWIG_BLOCK_MAGIC(op25, decoder_ff);
/*
* Publicly-accesible constuctor function for op25_decoder_f.
* Publicly-accesible constuctor function for op25_decoder_ff.
*/
op25_decoder_f_sptr op25_make_decoder_f(gr_msg_queue_sptr msgq);
op25_decoder_ff_sptr op25_make_decoder_ff(gr_msg_queue_sptr msgq);
/*
* The actual op25_decoder block.
*/
class op25_decoder_f : public gr_sync_block
class op25_decoder_ff : public gr_block
{
private:
op25_decoder_f(gr_msg_queue_sptr msgq);
op25_decoder_ff(gr_msg_queue_sptr msgq);
};

View File

@ -24,31 +24,43 @@
#include "config.h"
#endif
#include <op25_decoder_f.h>
#include <algorithm>
#include <op25_decoder_ff.h>
#include <gr_io_signature.h>
/*
* Create a new instance of op25_decoder_f and wrap it in a
* Create a new instance of op25_decoder_ff and wrap it in a
* shared_ptr. This is effectively the public constructor.
*/
op25_decoder_f_sptr
op25_make_decoder_f(gr_msg_queue_sptr msgq)
op25_decoder_ff_sptr
op25_make_decoder_ff(gr_msg_queue_sptr msgq)
{
return op25_decoder_f_sptr(new op25_decoder_f(msgq));
return op25_decoder_ff_sptr(new op25_decoder_ff(msgq));
}
/*
* Destruct an instance of this class.
*/
op25_decoder_f::~op25_decoder_f()
op25_decoder_ff::~op25_decoder_ff()
{
}
/*
* Estimate nof_input_items_reqd for a given nof_output_items.
*/
void
op25_decoder_ff::forecast(int nof_output_items, gr_vector_int &nof_input_items_reqd)
{
const int nof_symbols_per_LDU = 864;
const size_t nof_inputs = nof_input_items_reqd.size();
std::fill(&nof_input_items_reqd[0], &nof_input_items_reqd[nof_inputs], nof_symbols_per_LDU);
}
/*
* Take an incoming float value, convert to a dibit symbol and process.
*/
int
op25_decoder_f::work(int nof_output_items, gr_vector_const_void_star& input_items, gr_vector_void_star& output_items)
op25_decoder_ff::general_work(int nof_output_items, gr_vector_int& nof_input_items, gr_vector_const_void_star& input_items, gr_vector_void_star& output_items)
{
const float *in = reinterpret_cast<const float*>(input_items[0]);
for(int i = 0; i < nof_output_items; ++i) {
@ -64,14 +76,18 @@ op25_decoder_f::work(int nof_output_items, gr_vector_const_void_star& input_item
}
receive_symbol(d);
}
return nof_output_items;
// ToDo: get IMBE decoder to provide audio
float *out = reinterpret_cast<float*>(output_items[0]);
std::fill(&out[0], &out[nof_output_items], 0);
consume_each(nof_output_items);
return 0; // ToDo: return IMBE-decoded audio
}
/*
* The private constructor.
*/
op25_decoder_f::op25_decoder_f(gr_msg_queue_sptr msgq) :
gr_sync_block("decoder_f", gr_make_io_signature(1, 1, sizeof(float)), gr_make_io_signature(0, 0, 0)),
op25_decoder_ff::op25_decoder_ff(gr_msg_queue_sptr msgq) :
gr_block("decoder_ff", gr_make_io_signature(1, 1, sizeof(float)), gr_make_io_signature(1, 1, sizeof(float))),
d_msgq(msgq),
d_state(SYNCHRONIZING),
d_substate(IDENTIFYING),
@ -91,7 +107,7 @@ op25_decoder_f::op25_decoder_f(gr_msg_queue_sptr msgq) :
* sync value.
*/
bool
op25_decoder_f::correlates(dibit d)
op25_decoder_ff::correlates(dibit d)
{
size_t errs = 0;
const size_t ERR_THRESHOLD = 4;
@ -116,7 +132,7 @@ op25_decoder_f::correlates(dibit d)
* false. When found d_network_ID contains the network ID value.
*/
bool
op25_decoder_f::identifies(dibit d)
op25_decoder_ff::identifies(dibit d)
{
bool identified = false;
d_network_ID <<= 2;
@ -132,7 +148,7 @@ op25_decoder_f::identifies(dibit d)
* Process a received symbol.
*/
void
op25_decoder_f::receive_symbol(dibit d)
op25_decoder_ff::receive_symbol(dibit d)
{
switch(d_state) {
case SYNCHRONIZING:
@ -153,7 +169,7 @@ op25_decoder_f::receive_symbol(dibit d)
* Process a received symbol when synchronized.
*/
void
op25_decoder_f::sync_receive_symbol(dibit d)
op25_decoder_ff::sync_receive_symbol(dibit d)
{
switch(d_substate) {
case IDENTIFYING:
@ -169,6 +185,9 @@ op25_decoder_f::sync_receive_symbol(dibit d)
break;
case READING:
if(d_data_unit->complete(d)) {
// ToDo: ask data_unit to produce audio here
gr_message_sptr msg(d_data_unit->decode());
if(msg) {
d_msgq->insert_tail(msg);

View File

@ -20,31 +20,32 @@
* 02110-1301, USA.
*/
#ifndef INCLUDED_OP25_DECODER_F_H
#define INCLUDED_OP25_DECODER_F_H
#ifndef INCLUDED_OP25_DECODER_FF_H
#define INCLUDED_OP25_DECODER_FF_H
#include <data_unit.h>
#include <gr_sync_block.h>
#include <gr_block.h>
#include <gr_msg_queue.h>
typedef boost::shared_ptr<class op25_decoder_f> op25_decoder_f_sptr;
typedef boost::shared_ptr<class op25_decoder_ff> op25_decoder_ff_sptr;
op25_decoder_f_sptr op25_make_decoder_f(gr_msg_queue_sptr msgq);
op25_decoder_ff_sptr op25_make_decoder_ff(gr_msg_queue_sptr msgq);
/*
* op25_decoder_f is a GNU Radio block for decoding APCO P25
* op25_decoder_ff is a GNU Radio block for decoding APCO P25
* signals. This file expects its input to be a stream of symbols from
* the demodulator and is a signal sink that produces no outputs.
* Processed messages are sent to the message queue.
*/
class op25_decoder_f : public gr_sync_block
class op25_decoder_ff : public gr_block
{
public:
virtual ~op25_decoder_f();
virtual int work(int nof_output_items, gr_vector_const_void_star& input_items, gr_vector_void_star& output_items);
virtual ~op25_decoder_ff();
virtual void forecast(int nof_output_items, gr_vector_int &nof_input_items_reqd);
virtual int general_work(int nof_output_items, gr_vector_int& nof_input_items, gr_vector_const_void_star& input_items, gr_vector_void_star& output_items);
private:
friend op25_decoder_f_sptr op25_make_decoder_f(gr_msg_queue_sptr msgq); // expose class to public ctor
op25_decoder_f(gr_msg_queue_sptr msgq);
friend op25_decoder_ff_sptr op25_make_decoder_ff(gr_msg_queue_sptr msgq); // expose class to public ctor
op25_decoder_ff(gr_msg_queue_sptr msgq);
bool correlates(dibit d);
bool identifies(dibit d);
void receive_symbol(dibit d);
@ -61,4 +62,4 @@ private:
uint32_t d_unrecognized;
};
#endif /* INCLUDED_OP25_DECODER_F_H */
#endif /* INCLUDED_OP25_DECODER_FF_H */

View File

@ -21,7 +21,6 @@
#
from gnuradio import gr, gr_unittest
#from gnuradio import op25
import op25
# import os
@ -37,20 +36,15 @@ class qa_op25(gr_unittest.TestCase):
def tearDown(self):
self.fg = None
# def test_op25_decoder_f_ctor(self):
# msgq = gr.msg_queue()
# self.fg.connect(src, p25)
# p25 = op25.decoder_f(msgq)
# # assert not null
def test_correlator(self):
def test_constructor(self):
framing_sequence = (3, 3, 3, 3, 3, -3, 3, 3, -3, -3, 3, 3, -3, -3, -3, -3, 3, -3, 3, -3, -3, -3, -3, -3)
src = gr.vector_source_f(framing_sequence, False)
msgq = gr.msg_queue()
p25 = op25.decoder_f(msgq)
p25 = op25.decoder_ff(msgq)
self.fg.connect(src, p25)
bit_bucket = gr.null_sink(gr.sizeof_float)
self.fg.connect(p25, bit_bucket)
self.fg.run()
# check the msgq output (needs separate thread and terminate the flow graph)
if __name__ == '__main__':
gr_unittest.main ()