diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt
index c79e908..31275d9 100644
--- a/grc/CMakeLists.txt
+++ b/grc/CMakeLists.txt
@@ -49,5 +49,5 @@ if(${INCLUDE_DEBUG_BLOCKS})
endif()
install(FILES
${enabled_blocks}
- DESTINATION share/gnuradio/grc/blocks
+ satnogs_ogg_source.xml DESTINATION share/gnuradio/grc/blocks
)
diff --git a/grc/satnogs_block_tree.xml b/grc/satnogs_block_tree.xml
index 52f236b..bda94dd 100644
--- a/grc/satnogs_block_tree.xml
+++ b/grc/satnogs_block_tree.xml
@@ -14,6 +14,7 @@
satnogs_morse_decodersatnogs_multi_format_msg_sinksatnogs_ogg_encoder
+ satnogs_ogg_sourcesatnogs_cw_to_symbolsatnogs_sine_matched_filter_ffsatnogs_udp_msg_source
diff --git a/grc/satnogs_ogg_source.xml b/grc/satnogs_ogg_source.xml
new file mode 100644
index 0000000..9795555
--- /dev/null
+++ b/grc/satnogs_ogg_source.xml
@@ -0,0 +1,28 @@
+
+
+ OGG File Source
+ satnogs_ogg_source
+ [satnogs]
+ import satnogs
+ satnogs.ogg_source($filename, $channels)
+
+
+ File
+ filename
+
+ file_open
+
+
+
+ Channels
+ channels
+ 1
+ int
+
+
+
+ out
+ float
+ $channels
+
+
diff --git a/include/satnogs/CMakeLists.txt b/include/satnogs/CMakeLists.txt
index 2c16dc5..066dd1a 100644
--- a/include/satnogs/CMakeLists.txt
+++ b/include/satnogs/CMakeLists.txt
@@ -63,5 +63,5 @@ if(${INCLUDE_DEBUG_BLOCKS})
endif()
install(FILES
${HEADER_FILES}
- DESTINATION include/satnogs
+ ogg_source.h DESTINATION include/satnogs
)
\ No newline at end of file
diff --git a/include/satnogs/ogg_source.h b/include/satnogs/ogg_source.h
new file mode 100644
index 0000000..18de151
--- /dev/null
+++ b/include/satnogs/ogg_source.h
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
+ *
+ * Copyright (C) 2017, Libre Space Foundation
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 program. If not, see .
+ */
+
+#ifndef INCLUDED_SATNOGS_OGG_SOURCE_H
+#define INCLUDED_SATNOGS_OGG_SOURCE_H
+
+#include
+#include
+
+namespace gr
+{
+ namespace satnogs
+ {
+
+ /*!
+ * \brief OGG source block. Reads a file with an OGG audio and
+ * convert it to float samples
+ *
+ * \ingroup satnogs
+ *
+ */
+ class SATNOGS_API ogg_source : virtual public gr::sync_block
+ {
+ public:
+ typedef boost::shared_ptr sptr;
+
+ /*!
+ *
+ * @param filename the OGG audio file path
+ * @param number of channels of the OGG stream. If the actual OGG stream
+ * contains a different number of channels than specified an exception
+ * is raised
+ */
+ static sptr
+ make (const std::string& filename, size_t channels = 1);
+ };
+
+ } // namespace satnogs
+} // namespace gr
+
+#endif /* INCLUDED_SATNOGS_OGG_SOURCE_H */
+
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index cd5e06a..a5352a5 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -59,7 +59,8 @@ list(APPEND satnogs_sources
ax25_encoder_mb_impl.cc
ax25_decoder_bm_impl.cc
qb50_deframer_impl.cc
- waterfall_sink_impl.cc)
+ waterfall_sink_impl.cc
+ ogg_source_impl.cc)
if(${INCLUDE_DEBUG_BLOCKS})
list(APPEND satnogs_sources ${satnogs_debug_sources})
diff --git a/lib/ogg_source_impl.cc b/lib/ogg_source_impl.cc
new file mode 100644
index 0000000..8292faa
--- /dev/null
+++ b/lib/ogg_source_impl.cc
@@ -0,0 +1,125 @@
+/* -*- c++ -*- */
+/*
+ * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
+ *
+ * Copyright (C) 2017, Libre Space Foundation
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 program. If not, see .
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include
+#include
+#include
+
+#include "ogg_source_impl.h"
+
+#define PCM_BUF_SIZE 4096
+
+namespace gr {
+ namespace satnogs {
+
+ ogg_source::sptr
+ ogg_source::make(const std::string& filename, size_t channels)
+ {
+ return gnuradio::get_initial_sptr
+ (new ogg_source_impl(filename, channels));
+ }
+
+ /*
+ * The private constructor
+ */
+ ogg_source_impl::ogg_source_impl (const std::string& filename,
+ size_t channels) :
+ gr::sync_block (
+ "ogg_source", gr::io_signature::make (0, 0, 0),
+ gr::io_signature::make (channels, channels, sizeof(float))),
+ d_channels (channels)
+ {
+ if (channels < 1) {
+ throw std::invalid_argument ("At least one output channels should"
+ " be specified");
+ }
+
+ if (ov_fopen (filename.c_str (), &d_ogvorb_f) < 0) {
+ throw std::invalid_argument ("Invalid .ogg file");
+ }
+
+ vorbis_info *vi = ov_info(&d_ogvorb_f,-1);
+ if(vi->channels != (int) channels) {
+ throw std::invalid_argument (
+ std::string ("Channels number specified (")
+ + std::to_string (channels)
+ + ") does not match the channels of "
+ "the ogg stream (" + std::to_string (vi->channels) + ")");
+ }
+
+ const int alignment_multiple = volk_get_alignment() / sizeof(float);
+ set_alignment(std::max(1,alignment_multiple));
+ set_max_noutput_items(PCM_BUF_SIZE);
+
+ d_in_buffer = (int16_t *)volk_malloc(PCM_BUF_SIZE * sizeof(int16_t),
+ volk_get_alignment());
+ d_out_buffer = (float *)volk_malloc(PCM_BUF_SIZE * sizeof(float),
+ volk_get_alignment());
+ }
+
+ /*
+ * Our virtual destructor.
+ */
+ ogg_source_impl::~ogg_source_impl()
+ {
+ ov_clear(&d_ogvorb_f);
+ volk_free(d_in_buffer);
+ volk_free(d_out_buffer);
+ }
+
+ int
+ ogg_source_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ long int ret;
+ int section = 0;
+ int available = (noutput_items / d_channels);
+ int produced = 0;
+
+ ret = ov_read (&d_ogvorb_f, (char *)d_in_buffer,
+ available * sizeof(int16_t),
+ 0, sizeof(int16_t), 1, §ion);
+ if(ret < sizeof(int16_t)) {
+ return WORK_DONE;
+ }
+
+ /* Convert to float the signed-short audio samples */
+ volk_16i_s32f_convert_32f (d_out_buffer, d_in_buffer, 2 << 15,
+ ret / sizeof(int16_t));
+
+ /* De-interleave the available channels */
+ for(int i = 0; i < ret / sizeof(int16_t); i += d_channels, produced++) {
+ for(int chan = 0; chan < d_channels; chan++){
+ ((float *)output_items[chan])[produced] = d_out_buffer[i * d_channels + chan];
+ }
+ }
+
+ return produced;
+ }
+
+ } /* namespace satnogs */
+} /* namespace gr */
+
diff --git a/lib/ogg_source_impl.h b/lib/ogg_source_impl.h
new file mode 100644
index 0000000..3a73f4a
--- /dev/null
+++ b/lib/ogg_source_impl.h
@@ -0,0 +1,56 @@
+/* -*- c++ -*- */
+/*
+ * gr-satnogs: SatNOGS GNU Radio Out-Of-Tree Module
+ *
+ * Copyright (C) 2017, Libre Space Foundation
+ *
+ * This program 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 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 program. If not, see .
+ */
+
+#ifndef INCLUDED_SATNOGS_OGG_SOURCE_IMPL_H
+#define INCLUDED_SATNOGS_OGG_SOURCE_IMPL_H
+
+#include
+#include
+#include
+
+namespace gr
+{
+ namespace satnogs
+ {
+
+ class ogg_source_impl : public ogg_source
+ {
+ private:
+ const size_t d_channels;
+ OggVorbis_File d_ogvorb_f;
+
+ int16_t *d_in_buffer;
+ float *d_out_buffer;
+
+ public:
+ ogg_source_impl (const std::string& filename, size_t channels);
+ ~ogg_source_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 satnogs
+} // namespace gr
+
+#endif /* INCLUDED_SATNOGS_OGG_SOURCE_IMPL_H */
+
diff --git a/swig/satnogs_swig.i b/swig/satnogs_swig.i
index 8b3417a..bc54368 100644
--- a/swig/satnogs_swig.i
+++ b/swig/satnogs_swig.i
@@ -32,6 +32,7 @@
#include "satnogs/qb50_deframer.h"
#include "satnogs/waterfall_sink.h"
#include "satnogs/ogg_encoder.h"
+#include "satnogs/ogg_source.h"
%}
@@ -100,3 +101,5 @@ GR_SWIG_BLOCK_MAGIC2(satnogs, qb50_deframer);
GR_SWIG_BLOCK_MAGIC2(satnogs, waterfall_sink);
%include "satnogs/ogg_encoder.h"
GR_SWIG_BLOCK_MAGIC2(satnogs, ogg_encoder);
+%include "satnogs/ogg_source.h"
+GR_SWIG_BLOCK_MAGIC2(satnogs, ogg_source);