diff --git a/CMakeLists.txt b/CMakeLists.txt index c59725c..112e1f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,6 +116,7 @@ find_package (Threads REQUIRED) find_package(CppUnit) find_package(Doxygen) find_package(Volk REQUIRED) +find_package(OggVorbis REQUIRED) ######################################################################## # Include or not into the module blocks for debugging diff --git a/cmake/Modules/FindOggVorbis.cmake b/cmake/Modules/FindOggVorbis.cmake new file mode 100644 index 0000000..32835b0 --- /dev/null +++ b/cmake/Modules/FindOggVorbis.cmake @@ -0,0 +1,86 @@ +# - Try to find the OggVorbis libraries +# Once done this will define +# +# OGGVORBIS_FOUND - system has OggVorbis +# OGGVORBIS_VERSION - set either to 1 or 2 +# OGG_INCLUDE_DIR - the OggVorbis include directory +# VORBIS_INCLUDE_DIR - the OggVorbis include directory +# OGGVORBIS_LIBRARIES - The libraries needed to use OggVorbis +# OGG_LIBRARY - The Ogg library +# VORBIS_LIBRARY - The Vorbis library +# VORBISFILE_LIBRARY - The VorbisFile library +# VORBISENC_LIBRARY - The VorbisEnc library + +# Copyright (c) 2006, Richard Laerkaeng, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + + +include (CheckLibraryExists) + +find_path(VORBIS_INCLUDE_DIR vorbis/vorbisfile.h) +find_path(OGG_INCLUDE_DIR ogg/ogg.h) + +find_library(OGG_LIBRARY NAMES ogg) +find_library(VORBIS_LIBRARY NAMES vorbis) +find_library(VORBISFILE_LIBRARY NAMES vorbisfile) +find_library(VORBISENC_LIBRARY NAMES vorbisenc) + + +if (VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY AND VORBISENC_LIBRARY) + set(OGGVORBIS_FOUND TRUE) + + set(OGGVORBIS_LIBRARIES ${OGG_LIBRARY} ${VORBIS_LIBRARY} ${VORBISFILE_LIBRARY} ${VORBISENC_LIBRARY}) + + set(_CMAKE_REQUIRED_LIBRARIES_TMP ${CMAKE_REQUIRED_LIBRARIES}) + set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${OGGVORBIS_LIBRARIES}) + check_library_exists(vorbis vorbis_bitrate_addblock "" HAVE_LIBVORBISENC2) + set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_TMP}) + + if (HAVE_LIBVORBISENC2) + set (OGGVORBIS_VERSION 2) + else (HAVE_LIBVORBISENC2) + set (OGGVORBIS_VERSION 1) + endif (HAVE_LIBVORBISENC2) + +else (VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY AND VORBISENC_LIBRARY) + set (OGGVORBIS_VERSION) + set(OGGVORBIS_FOUND FALSE) +endif (VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY AND VORBISENC_LIBRARY) + + +if (OGGVORBIS_FOUND) + if (NOT OggVorbis_FIND_QUIETLY) + message(STATUS "Found OggVorbis: ${OGGVORBIS_LIBRARIES}") + endif (NOT OggVorbis_FIND_QUIETLY) +else (OGGVORBIS_FOUND) + if (OggVorbis_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find OggVorbis libraries") + endif (OggVorbis_FIND_REQUIRED) + if (NOT OggVorbis_FIND_QUITELY) + message(STATUS "Could NOT find OggVorbis libraries") + endif (NOT OggVorbis_FIND_QUITELY) +endif (OGGVORBIS_FOUND) + +#check_include_files(vorbis/vorbisfile.h HAVE_VORBISFILE_H) +#check_library_exists(ogg ogg_page_version "" HAVE_LIBOGG) +#check_library_exists(vorbis vorbis_info_init "" HAVE_LIBVORBIS) +#check_library_exists(vorbisfile ov_open "" HAVE_LIBVORBISFILE) +#check_library_exists(vorbisenc vorbis_info_clear "" HAVE_LIBVORBISENC) +#check_library_exists(vorbis vorbis_bitrate_addblock "" HAVE_LIBVORBISENC2) + +#if (HAVE_LIBOGG AND HAVE_VORBISFILE_H AND HAVE_LIBVORBIS AND HAVE_LIBVORBISFILE AND HAVE_LIBVORBISENC) +# message(STATUS "Ogg/Vorbis found") +# set (VORBIS_LIBS "-lvorbis -logg") +# set (VORBISFILE_LIBS "-lvorbisfile") +# set (VORBISENC_LIBS "-lvorbisenc") +# set (OGGVORBIS_FOUND TRUE) +# if (HAVE_LIBVORBISENC2) +# set (HAVE_VORBIS 2) +# else (HAVE_LIBVORBISENC2) +# set (HAVE_VORBIS 1) +# endif (HAVE_LIBVORBISENC2) +#else (HAVE_LIBOGG AND HAVE_VORBISFILE_H AND HAVE_LIBVORBIS AND HAVE_LIBVORBISFILE AND HAVE_LIBVORBISENC) +# message(STATUS "Ogg/Vorbis not found") +#endif (HAVE_LIBOGG AND HAVE_VORBISFILE_H AND HAVE_LIBVORBIS AND HAVE_LIBVORBISFILE AND HAVE_LIBVORBISENC) \ No newline at end of file diff --git a/grc/CMakeLists.txt b/grc/CMakeLists.txt index 40d66ab..c79e908 100644 --- a/grc/CMakeLists.txt +++ b/grc/CMakeLists.txt @@ -31,6 +31,7 @@ list(APPEND enabled_blocks satnogs_cw_matched_filter_ff.xml satnogs_morse_decoder.xml satnogs_multi_format_msg_sink.xml + satnogs_ogg_encoder.xml satnogs_cw_to_symbol.xml satnogs_sine_matched_filter_ff.xml satnogs_udp_msg_source.xml @@ -48,5 +49,5 @@ if(${INCLUDE_DEBUG_BLOCKS}) endif() install(FILES ${enabled_blocks} - satnogs_ogg_enc.xml DESTINATION share/gnuradio/grc/blocks + DESTINATION share/gnuradio/grc/blocks ) diff --git a/grc/satnogs_block_tree.xml b/grc/satnogs_block_tree.xml index ee61c74..52f236b 100644 --- a/grc/satnogs_block_tree.xml +++ b/grc/satnogs_block_tree.xml @@ -13,6 +13,7 @@ satnogs_cw_matched_filter_ff satnogs_morse_decoder satnogs_multi_format_msg_sink + satnogs_ogg_encoder satnogs_cw_to_symbol satnogs_sine_matched_filter_ff satnogs_udp_msg_source diff --git a/grc/satnogs_ogg_enc.xml b/grc/satnogs_ogg_enc.xml deleted file mode 100644 index d5a47f5..0000000 --- a/grc/satnogs_ogg_enc.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - ogg_enc - satnogs_ogg_enc - [satnogs] - import satnogs - satnogs.ogg_enc($filename, $samp_rate, $quality) - - - ... - ... - ... - - - - - in - - - - - - out - - - diff --git a/grc/satnogs_ogg_encoder.xml b/grc/satnogs_ogg_encoder.xml new file mode 100644 index 0000000..6154ded --- /dev/null +++ b/grc/satnogs_ogg_encoder.xml @@ -0,0 +1,32 @@ + + + OGG Encoder + satnogs_ogg_encoder + import satnogs + satnogs.ogg_encoder($filename, $samp_rate, $quality) + + + File + filename + + file_save + + + + Sampling rate + samp_rate + real + + + + Quality + quality + 0.8 + real + + + + in + float + + diff --git a/include/satnogs/CMakeLists.txt b/include/satnogs/CMakeLists.txt index 7f65a8a..2c16dc5 100644 --- a/include/satnogs/CMakeLists.txt +++ b/include/satnogs/CMakeLists.txt @@ -37,6 +37,7 @@ list(APPEND HEADER_FILES morse.h morse_decoder.h multi_format_msg_sink.h + ogg_encoder.h cw_to_symbol.h sine_matched_filter_ff.h utils.h @@ -61,6 +62,6 @@ if(${INCLUDE_DEBUG_BLOCKS}) list(APPEND HEADER_FILES ${DEBUG_HEADER_FILES}) endif() install(FILES - ${HEADER_FILES} - ogg_enc.h DESTINATION include/satnogs + ${HEADER_FILES} + DESTINATION include/satnogs ) \ No newline at end of file diff --git a/include/satnogs/ogg_enc.h b/include/satnogs/ogg_encoder.h similarity index 72% rename from include/satnogs/ogg_enc.h rename to include/satnogs/ogg_encoder.h index 45bf948..18bd62c 100644 --- a/include/satnogs/ogg_enc.h +++ b/include/satnogs/ogg_encoder.h @@ -24,28 +24,29 @@ #include #include -namespace gr { - namespace satnogs { +namespace gr +{ + namespace satnogs + { /*! - * \brief <+description of block+> + * \brief Ogg encoder and sink block * \ingroup satnogs * */ class SATNOGS_API ogg_encoder : virtual public gr::sync_block { - public: + public: typedef boost::shared_ptr sptr; /*! - * \brief Return a shared_ptr to a new instance of satnogs::ogg_encoder. - * - * To avoid accidental use of raw pointers, satnogs::ogg_encoder's - * constructor is in a private implementation - * class. satnogs::ogg_encoder::make is the public interface for - * creating new instances. + * Ogg encoder and sink block. + * @param filename filename of the output file + * @param samp_rate the sampling rate + * @param quality the quality of the output file. [0.1 - 1.0] (worst - best) */ - static sptr make(char* filename, double samp_rate, float quality); + static sptr + make (char* filename, double samp_rate, float quality); }; } // namespace satnogs diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 8f7f8cd..15bcb14 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -25,7 +25,8 @@ include(GrPlatform) #define LIB_SUFFIX include_directories( ${Boost_INCLUDE_DIR} ${VOLK_INCLUDE_DIRS} - ${OGG_INCLUDE_DIRS} + ${VORBIS_INCLUDE_DIR} + ${OGG_INCLUDE_DIR} ) link_directories(${Boost_LIBRARY_DIRS}) @@ -41,6 +42,7 @@ list(APPEND satnogs_sources morse_tree.cc morse_decoder_impl.cc multi_format_msg_sink_impl.cc + ogg_encoder_impl.cc cw_to_symbol_impl.cc sine_matched_filter_ff_impl.cc udp_msg_source_impl.cc @@ -57,8 +59,7 @@ list(APPEND satnogs_sources ax25_encoder_mb_impl.cc ax25_decoder_bm_impl.cc qb50_deframer_impl.cc - waterfall_sink_impl.cc - ogg_enc_impl.cc ) + waterfall_sink_impl.cc) if(${INCLUDE_DEBUG_BLOCKS}) list(APPEND satnogs_sources ${satnogs_debug_sources}) @@ -78,9 +79,7 @@ target_link_libraries(gnuradio-satnogs ${CMAKE_THREAD_LIBS_INIT} ${NOVA_LIBRARIES} ${VOLK_LIBRARIES} - ogg - vorbis - vorbisenc + ${OGGVORBIS_LIBRARIES} ) set_target_properties(gnuradio-satnogs PROPERTIES DEFINE_SYMBOL "gnuradio_satnogs_EXPORTS") diff --git a/lib/ogg_enc_impl.cc b/lib/ogg_enc_impl.cc deleted file mode 100644 index 8d63b73..0000000 --- a/lib/ogg_enc_impl.cc +++ /dev/null @@ -1,135 +0,0 @@ -/* -*- 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 "ogg_encoder_impl.h" - -#include -#include -#include -#include -#include - - -namespace gr { - namespace satnogs { - - ogg_encoder::sptr - ogg_encoder::make(char* filename, double samp_rate, float quality) - { - return gnuradio::get_initial_sptr - (new ogg_encoder_impl(filename, samp_rate, quality)); - } - - /* - * The private constructor - */ - ogg_encoder_impl::ogg_encoder_impl(char* filename, double samp_rate, float quality) - : gr::sync_block("ogg_encoder", - gr::io_signature::make(1, 1, sizeof(float)), - gr::io_signature::make(0, 0, 0)) - { - d_quality = quality; - d_out=fopen(filename,"wb"); - d_samp_rate = samp_rate; - vorbis_info_init(&d_vi); - int ret = vorbis_encode_init_vbr(&d_vi,1,d_samp_rate,d_quality); - if(ret)exit(1); - - vorbis_comment_init(&d_vc); - vorbis_comment_add_tag(&d_vc, "ENCODER", "satnogs ogg encoder"); - - vorbis_analysis_init(&d_vd, &d_vi); - vorbis_block_init(&d_vd, &d_vb); - - srand(time(NULL)); - ogg_stream_init(&d_os, rand()); - - ogg_packet header; - ogg_packet header_comm; - ogg_packet header_code; - - vorbis_analysis_headerout(&d_vd, &d_vc, &header, &header_comm, &header_code); - ogg_stream_packetin(&d_os, &header); - ogg_stream_packetin(&d_os, &header_comm); - ogg_stream_packetin(&d_os, &header_code); - int result = 1; - while(result){ - result=ogg_stream_flush(&d_os,&d_og); - if(result==0)break; - fwrite(d_og.header,1,d_og.header_len,d_out); - fwrite(d_og.body,1,d_og.body_len,d_out); - } - } - - ogg_encoder_impl::~ogg_encoder_impl() - { - vorbis_analysis_wrote(&d_vd,0); - ogg_stream_clear(&d_os); - vorbis_block_clear(&d_vb); - vorbis_dsp_clear(&d_vd); - vorbis_comment_clear(&d_vc); - vorbis_info_clear(&d_vi); - fclose(d_out); - } - - int - ogg_encoder_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { - size_t chunks = (noutput_items*sizeof(float))/2; - const signed char *in = (const signed char *) input_items[0]; - int i; - long bytes = 1024; - float **buffer=vorbis_analysis_buffer(&d_vd,chunks); - for(i=0;i + * + * 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 "ogg_encoder_impl.h" + +#include +#include +#include +#include +#include + +namespace gr +{ + namespace satnogs + { + + ogg_encoder::sptr + ogg_encoder::make (char* filename, double samp_rate, float quality) + { + return gnuradio::get_initial_sptr ( + new ogg_encoder_impl (filename, samp_rate, quality)); + } + + /* + * The private constructor + */ + ogg_encoder_impl::ogg_encoder_impl (char* filename, double samp_rate, + float quality) : + gr::sync_block ("ogg_encoder", + gr::io_signature::make (1, 1, sizeof(float)), + gr::io_signature::make (0, 0, 0)) + { + d_quality = quality; + d_out = fopen (filename, "wb"); + d_samp_rate = samp_rate; + vorbis_info_init (&d_vi); + int ret = vorbis_encode_init_vbr (&d_vi, 1, d_samp_rate, d_quality); + if (ret) + exit (1); + + vorbis_comment_init (&d_vc); + vorbis_comment_add_tag (&d_vc, "ENCODER", "satnogs ogg encoder"); + + vorbis_analysis_init (&d_vd, &d_vi); + vorbis_block_init (&d_vd, &d_vb); + + srand (time (NULL)); + ogg_stream_init (&d_os, rand ()); + + ogg_packet header; + ogg_packet header_comm; + ogg_packet header_code; + + vorbis_analysis_headerout (&d_vd, &d_vc, &header, &header_comm, + &header_code); + ogg_stream_packetin (&d_os, &header); + ogg_stream_packetin (&d_os, &header_comm); + ogg_stream_packetin (&d_os, &header_code); + int result = 1; + while (result) { + result = ogg_stream_flush (&d_os, &d_og); + if (result == 0) + break; + fwrite (d_og.header, 1, d_og.header_len, d_out); + fwrite (d_og.body, 1, d_og.body_len, d_out); + } + } + + ogg_encoder_impl::~ogg_encoder_impl () + { + vorbis_analysis_wrote (&d_vd, 0); + ogg_stream_clear (&d_os); + vorbis_block_clear (&d_vb); + vorbis_dsp_clear (&d_vd); + vorbis_comment_clear (&d_vc); + vorbis_info_clear (&d_vi); + fclose (d_out); + } + + int + ogg_encoder_impl::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const char *in = (const char *) input_items[0]; + int i; + float **buffer = vorbis_analysis_buffer (&d_vd, noutput_items); + memcpy(buffer[0], in, noutput_items * sizeof(float)); + + vorbis_analysis_wrote (&d_vd, noutput_items); + + while (vorbis_analysis_blockout (&d_vd, &d_vb) == 1) { + vorbis_analysis (&d_vb, NULL); + vorbis_bitrate_addblock (&d_vb); + + while (vorbis_bitrate_flushpacket (&d_vd, &d_op)) { + + ogg_stream_packetin (&d_os, &d_op); + int result = 1; + while (result) { + int result = ogg_stream_pageout (&d_os, &d_og); + if (result == 0) + break; + fwrite (d_og.header, 1, d_og.header_len, d_out); + fwrite (d_og.body, 1, d_og.body_len, d_out); + if (ogg_page_eos (&d_og)) + result = 1; + } + } + } + return noutput_items; + } + + } /* namespace satnogs */ +} /* namespace gr */ diff --git a/lib/ogg_enc_impl.h b/lib/ogg_encoder_impl.h similarity index 67% rename from lib/ogg_enc_impl.h rename to lib/ogg_encoder_impl.h index 23e8762..c8cf28b 100644 --- a/lib/ogg_enc_impl.h +++ b/lib/ogg_encoder_impl.h @@ -18,41 +18,42 @@ * along with this program. If not, see . */ - #ifndef INCLUDED_SATNOGS_OGG_ENCODER_IMPL_H #define INCLUDED_SATNOGS_OGG_ENCODER_IMPL_H #include #include -namespace gr { - namespace satnogs { +namespace gr +{ + namespace satnogs + { class ogg_encoder_impl : public ogg_encoder { - private: + private: // Nothing to declare in this block. - ogg_stream_state d_os; - ogg_page d_og; - ogg_packet d_op; + ogg_stream_state d_os; + ogg_page d_og; + ogg_packet d_op; - vorbis_info d_vi; - vorbis_comment d_vc; + vorbis_info d_vi; + vorbis_comment d_vc; - vorbis_dsp_state d_vd; - vorbis_block d_vb; - FILE* d_out; - double d_samp_rate; - float d_quality; + vorbis_dsp_state d_vd; + vorbis_block d_vb; + FILE* d_out; + double d_samp_rate; + float d_quality; - public: - ogg_encoder_impl(char* filename, double samp_rate, float quality); - ~ogg_encoder_impl(); + public: + ogg_encoder_impl (char* filename, double samp_rate, float quality); + ~ogg_encoder_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); + int + work (int noutput_items, gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; } // namespace satnogs diff --git a/swig/satnogs_swig.i b/swig/satnogs_swig.i index 95ad4a6..8b3417a 100644 --- a/swig/satnogs_swig.i +++ b/swig/satnogs_swig.i @@ -31,7 +31,7 @@ #include "satnogs/ax25_decoder_bm.h" #include "satnogs/qb50_deframer.h" #include "satnogs/waterfall_sink.h" -#include "satnogs/ogg_enc.h" +#include "satnogs/ogg_encoder.h" %} @@ -98,5 +98,5 @@ GR_SWIG_BLOCK_MAGIC2(satnogs, qb50_deframer); %include "satnogs/waterfall_sink.h" GR_SWIG_BLOCK_MAGIC2(satnogs, waterfall_sink); -%include "satnogs/ogg_enc.h" -GR_SWIG_BLOCK_MAGIC2(satnogs, ogg_enc); +%include "satnogs/ogg_encoder.h" +GR_SWIG_BLOCK_MAGIC2(satnogs, ogg_encoder);