summaryrefslogtreecommitdiff
path: root/gr-vocoder/lib
diff options
context:
space:
mode:
authorA. Maitland Bottoms <bottoms@debian.org>2016-09-15 10:51:41 -0400
committerA. Maitland Bottoms <bottoms@debian.org>2016-09-15 10:51:41 -0400
commitc2742b622252fbd51365c84bb3e4bc72a256a624 (patch)
tree940ed4b20e603ff74c898cea8219db3430f4561c /gr-vocoder/lib
parentaf4323d1e471476efa255e3df745397f7c8a1b71 (diff)
gr-vocoder freedv blocks
Diffstat (limited to 'gr-vocoder/lib')
-rw-r--r--gr-vocoder/lib/CMakeLists.txt7
-rw-r--r--gr-vocoder/lib/freedv_api.cc33
-rw-r--r--gr-vocoder/lib/freedv_rx_ss_impl.cc155
-rw-r--r--gr-vocoder/lib/freedv_rx_ss_impl.h81
-rw-r--r--gr-vocoder/lib/freedv_tx_ss_impl.cc98
-rw-r--r--gr-vocoder/lib/freedv_tx_ss_impl.h72
6 files changed, 446 insertions, 0 deletions
diff --git a/gr-vocoder/lib/CMakeLists.txt b/gr-vocoder/lib/CMakeLists.txt
index 5e806a2c2c..e26cb1820a 100644
--- a/gr-vocoder/lib/CMakeLists.txt
+++ b/gr-vocoder/lib/CMakeLists.txt
@@ -61,6 +61,13 @@ if(LIBCODEC2_FOUND)
codec2_encode_sp_impl.cc
)
endif(LIBCODEC2_FOUND)
+if(LIBCODEC2_HAS_FREEDV_API)
+ list(APPEND gr_vocoder_sources
+ freedv_api.cc
+ freedv_rx_ss_impl.cc
+ freedv_tx_ss_impl.cc
+ )
+endif(LIBCODEC2_HAS_FREEDV_API)
if(LIBGSM_FOUND)
list(APPEND gr_vocoder_sources
gsm_fr_decode_ps_impl.cc
diff --git a/gr-vocoder/lib/freedv_api.cc b/gr-vocoder/lib/freedv_api.cc
new file mode 100644
index 0000000000..063a6bb9f0
--- /dev/null
+++ b/gr-vocoder/lib/freedv_api.cc
@@ -0,0 +1,33 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2016 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 <gnuradio/vocoder/freedv_api.h>
+
+namespace gr {
+ namespace vocoder {
+
+ } /* namespace vocoder */
+} /* namespace gr */
diff --git a/gr-vocoder/lib/freedv_rx_ss_impl.cc b/gr-vocoder/lib/freedv_rx_ss_impl.cc
new file mode 100644
index 0000000000..6cb52effa2
--- /dev/null
+++ b/gr-vocoder/lib/freedv_rx_ss_impl.cc
@@ -0,0 +1,155 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2016 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 "freedv_rx_ss_impl.h"
+
+#include <gnuradio/io_signature.h>
+#include <stdexcept>
+#include <assert.h>
+
+extern "C" {
+ void put_next_rx_char(void *callback_state, char c) {
+ struct freedv_rx_callback_state* pstate;
+
+ pstate = (struct freedv_rx_callback_state*) callback_state;
+ if (pstate->ftxt != NULL) {
+ //fprintf(pstate->ftxt, "%c\n", c);
+ }
+ return;
+ }
+}
+
+
+namespace gr {
+ namespace vocoder {
+
+ freedv_rx_ss::sptr
+ freedv_rx_ss::make(int mode, float squelch_thresh)
+ {
+ return gnuradio::get_initial_sptr
+ (new freedv_rx_ss_impl(mode, squelch_thresh));
+ }
+
+ freedv_rx_ss_impl::freedv_rx_ss_impl (int mode, float squelch_thresh)
+ : gr::block("vocoder_freedv_rx_ss",
+ io_signature::make(1, 1, sizeof(short)),
+ io_signature::make(1, 1, sizeof(short))),
+ d_mode(mode), d_squelch_thresh(squelch_thresh)
+ {
+ if((d_freedv = freedv_open(mode)) == NULL)
+ throw std::runtime_error("freedv_rx_ss_impl: freedv_open failed");
+ freedv_set_snr_squelch_thresh(d_freedv, d_squelch_thresh);
+ freedv_set_squelch_en(d_freedv, 0);
+ freedv_set_callback_txt(d_freedv, put_next_rx_char, NULL, (void *) &d_cb_state);
+ d_speech_samples = freedv_get_n_speech_samples(d_freedv);
+ d_max_modem_samples = freedv_get_n_max_modem_samples(d_freedv);
+ d_nin = freedv_nin(d_freedv);
+ //set_output_multiple(d_max_modem_samples);
+ }
+
+ freedv_rx_ss_impl::~freedv_rx_ss_impl()
+ {
+ int total_bits;
+ int total_bit_errors;
+
+ if (freedv_get_test_frames(d_freedv)) {
+ total_bits = freedv_get_total_bits(d_freedv);
+ total_bit_errors = freedv_get_total_bit_errors(d_freedv);
+ fprintf(stderr, "bits: %d errors: %d BER: %3.2f\n", total_bits, total_bit_errors, (1.0*total_bit_errors)/total_bits);
+ }
+ freedv_close(d_freedv);
+ }
+
+ void
+ freedv_rx_ss_impl::forecast(int noutput_items,
+ gr_vector_int &ninput_items_required)
+ {
+ unsigned ninputs = ninput_items_required.size();
+ for(unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = noutput_items;
+ }
+
+ int
+ freedv_rx_ss_impl::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ short *in = (short *) input_items[0];
+ short *out = (short *) output_items[0];
+ int i,n;
+
+ d_nin = freedv_nin(d_freedv);
+ if (ninput_items[0] < d_nin) {
+ consume_each(0);
+ return(0);
+ }
+ for (i=0,n=0; ((n+d_nin) <= noutput_items)&&(i <= ninput_items[0]);) {
+ d_nout = freedv_rx(d_freedv, out, in);
+ i += d_nin;
+ n += d_nout;
+ out = &(out[d_nout]);
+ in = &(in[d_nin]);
+ d_nin = freedv_nin(d_freedv);
+ }
+ if ((i > ninput_items[0])||((n+d_nin) > noutput_items)) {
+ i -= d_nin;
+ n -= d_nout;
+ } // back up to where we left off processing freedv_rx
+
+ freedv_get_modem_stats(d_freedv, &d_sync, &d_snr_est);
+ freedv_get_modem_extended_stats(d_freedv, &d_stats);
+ d_total_bit_errors = freedv_get_total_bit_errors(d_freedv);
+
+ consume_each(i);
+ return(n);
+ }
+
+ void put_next_rx_proto(void *callback_state,char *proto_bits) {
+ return;
+ }
+
+ void datarx(void *callback_state, unsigned char *packet, size_t size) {
+ return;
+ }
+
+ void datatx(void *callback_state, unsigned char *packet, size_t *size) {
+ return;
+ }
+
+ void freedv_rx_ss_impl::set_squelch_thresh(float squelch_thresh)
+ {
+ gr::thread::scoped_lock l(d_setlock);
+ d_squelch_thresh = squelch_thresh;
+ freedv_set_snr_squelch_thresh(d_freedv, d_squelch_thresh);
+ }
+
+ float freedv_rx_ss_impl::squelch_thresh() {
+ return(d_squelch_thresh);
+ }
+
+ } /* namespace vocoder */
+} /* namespace gr */
diff --git a/gr-vocoder/lib/freedv_rx_ss_impl.h b/gr-vocoder/lib/freedv_rx_ss_impl.h
new file mode 100644
index 0000000000..911355b038
--- /dev/null
+++ b/gr-vocoder/lib/freedv_rx_ss_impl.h
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2016 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_VOCODER_FREEDV_RX_SS_IMPL_H
+#define INCLUDED_VOCODER_FREEDV_RX_SS_IMPL_H
+
+#include <gnuradio/vocoder/freedv_rx_ss.h>
+
+extern "C" {
+ struct freedv_rx_callback_state {
+ FILE *ftxt;
+ };
+ static void put_next_rx_char(void *callback_state, char c);
+ void put_next_rx_proto(void *callback_state,char *proto_bits);
+ void datarx(void *callback_state, unsigned char *packet, size_t size);
+ void datatx(void *callback_state, unsigned char *packet, size_t *size);
+}
+
+namespace gr {
+ namespace vocoder {
+
+ class freedv_rx_ss_impl : public freedv_rx_ss
+ {
+ private:
+ short *d_speech_out;
+ short *d_demod_in;
+ struct freedv *d_freedv;
+ int d_nin, d_nout, d_frame;
+ struct freedv_rx_callback_state d_cb_state;
+ struct MODEM_STATS d_stats;
+ int d_mode;
+ int d_sync;
+ int d_total_bits;
+ int d_total_bit_errors;
+ float d_snr_est;
+ float d_squelch_thresh;
+ int d_speech_samples;
+ int d_max_modem_samples;
+ float d_clock_offset;
+ int d_use_codecrx;
+ struct CODEC2 *d_c2 = NULL;
+
+ public:
+ freedv_rx_ss_impl(int mode, float squelch_thresh);
+ ~freedv_rx_ss_impl();
+
+ void set_squelch_thresh(float squelch_thresh);
+ float squelch_thresh();
+
+ // 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 vocoder */
+} /* namespace gr */
+
+#endif /* INCLUDED_VOCODER_FREEDV_RX_SS_IMPL_H */
diff --git a/gr-vocoder/lib/freedv_tx_ss_impl.cc b/gr-vocoder/lib/freedv_tx_ss_impl.cc
new file mode 100644
index 0000000000..d8cf04df43
--- /dev/null
+++ b/gr-vocoder/lib/freedv_tx_ss_impl.cc
@@ -0,0 +1,98 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2016 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 "freedv_tx_ss_impl.h"
+
+#include <gnuradio/io_signature.h>
+#include <stdexcept>
+#include <iostream>
+#include <iomanip>
+
+extern "C" {
+ char
+ get_next_tx_char(void *callback_state)
+ {
+ char c;
+ struct freedv_tx_callback_state* pstate;
+
+ pstate = (struct freedv_tx_callback_state*)callback_state;
+ c = *pstate->ptx_str++;
+
+ if (*pstate->ptx_str == 0) {
+ pstate->ptx_str = pstate->tx_str;
+ c = 0x0d; // FreeDV uses Carriage Return termination
+ }
+
+ return c;
+ }
+}
+
+namespace gr {
+ namespace vocoder {
+
+ freedv_tx_ss::sptr
+ freedv_tx_ss::make(int mode, const std::string msg_txt)
+ {
+ return gnuradio::get_initial_sptr
+ (new freedv_tx_ss_impl(mode, msg_txt));
+ }
+
+ freedv_tx_ss_impl::freedv_tx_ss_impl(int mode, const std::string msg_txt)
+ : sync_block("vocoder_freedv_tx_ss",
+ io_signature::make(1, 1, sizeof(short)),
+ io_signature::make(1, 1, sizeof(short))),
+ d_mode(mode), d_msg_text(msg_txt)
+ {
+ if((d_freedv = freedv_open(mode)) == NULL)
+ throw std::runtime_error("freedv_tx_ss_impl: freedv_open failed");
+ snprintf(d_cb_state.tx_str,79,"%s",d_msg_text.c_str());
+ d_cb_state.ptx_str = d_cb_state.tx_str;
+ freedv_set_callback_txt(d_freedv, NULL, get_next_tx_char, (void *) &d_cb_state);
+ d_nom_modem_samples = freedv_get_n_nom_modem_samples(d_freedv);
+ set_output_multiple(d_nom_modem_samples);
+ }
+
+ freedv_tx_ss_impl::~freedv_tx_ss_impl()
+ {
+ freedv_close(d_freedv);
+ }
+
+ int
+ freedv_tx_ss_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ short *in = (short*)input_items[0];
+ short *out = (short*)output_items[0];
+ int i;
+
+ for(i=0;i<(noutput_items/d_nom_modem_samples);i++)
+ freedv_tx(d_freedv, &(out[i*d_nom_modem_samples]), &(in[i*d_nom_modem_samples]));
+ return noutput_items;
+ }
+
+ } /* namespace vocoder */
+} /* namespace gr */
diff --git a/gr-vocoder/lib/freedv_tx_ss_impl.h b/gr-vocoder/lib/freedv_tx_ss_impl.h
new file mode 100644
index 0000000000..4a24d3b281
--- /dev/null
+++ b/gr-vocoder/lib/freedv_tx_ss_impl.h
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2016 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_VOCODER_FREEDV_TX_SS_IMPL_H
+#define INCLUDED_VOCODER_FREEDV_TX_SS_IMPL_H
+
+#include <gnuradio/vocoder/freedv_tx_ss.h>
+
+extern "C" {
+ struct freedv_tx_callback_state {
+ char tx_str[80];
+ char *ptx_str;
+ int calls;
+ };
+ char get_next_tx_char(void *callback_state);
+ void get_next_proto(void *callback_state,char *proto_bits);
+ void datarx(void *callback_state, unsigned char *packet, size_t size);
+ void datatx(void *callback_state, unsigned char *packet, size_t *size);
+}
+
+namespace gr {
+ namespace vocoder {
+
+ class freedv_tx_ss_impl : public freedv_tx_ss
+ {
+ private:
+ short *d_speech_in;
+ short *d_mod_out;
+ struct freedv_tx_callback_state d_cb_state;
+ struct freedv *d_freedv;
+ int d_mode;
+ float d_squelch_thresh;
+ int d_speech_samples;
+ int d_nom_modem_samples;
+ int d_use_codectx;
+ int d_use_datatx;
+ std::string d_msg_text;
+ struct CODEC2 *d_c2;
+
+ public:
+ freedv_tx_ss_impl(int mode, const std::string txt_msg);
+ ~freedv_tx_ss_impl();
+
+ // Where all the action really happens
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+ };
+
+ } /* namespace vocoder */
+} /* namespace gr */
+
+#endif /* INCLUDED_VOCODER_FREEDV_TX_SS_IMPL_H */