From 6c72554e43c8bc1e35d8baa7a8271772c85fa48e Mon Sep 17 00:00:00 2001
From: "A. Maitland Bottoms" <bottoms@debian.org>
Date: Sat, 10 Feb 2018 20:40:35 -0500
Subject: [PATCH 11/27] gr-vocoder codec2 subcomponent using external codec2

Newer distributions use newer Codec2 libraries. Gnuradio
should use those for better interoperability.
---
 cmake/Modules/FindCodec2.cmake                     | 67 +++++++++++++++++
 gr-vocoder/CMakeLists.txt                          | 15 ++++
 gr-vocoder/examples/CMakeLists.txt                 |  9 ++-
 gr-vocoder/grc/CMakeLists.txt                      | 11 ++-
 gr-vocoder/grc/vocoder_codec2_decode_ps.xml        | 10 ++-
 gr-vocoder/grc/vocoder_codec2_encode_sp.xml        | 10 ++-
 gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt | 10 +++
 gr-vocoder/include/gnuradio/vocoder/codec2.h       | 10 ++-
 gr-vocoder/lib/CMakeLists.txt                      | 83 +++-------------------
 gr-vocoder/python/vocoder/CMakeLists.txt           | 15 +++-
 gr-vocoder/swig/CMakeLists.txt                     |  4 ++
 gr-vocoder/swig/vocoder_swig.i                     | 25 ++++---
 12 files changed, 179 insertions(+), 90 deletions(-)
 create mode 100644 cmake/Modules/FindCodec2.cmake

--- /dev/null
+++ b/cmake/Modules/FindCodec2.cmake
@@ -0,0 +1,67 @@
+# 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.
+
+##############################
+# Check for system libcodec2 #
+##############################
+
+INCLUDE(FindPkgConfig)
+INCLUDE(FindPackageHandleStandardArgs)
+
+pkg_check_modules(LIBCODEC2_PKG QUIET codec2)
+
+find_path(LIBCODEC2_INCLUDE_DIR NAMES codec2.h
+  PATHS
+  ${LIBCODEC2_PKG_INCLUDE_DIRS}
+  /usr/include/codec2
+  /usr/include
+  /usr/local/include/codec2
+  /usr/local/include
+  )
+
+find_library(LIBCODEC2_LIBRARIES NAMES codec2
+  PATHS
+  ${LIBCODEC2_PKG_LIBRARY_DIRS}
+  /usr/lib
+  /usr/local/lib
+  )
+
+if(LIBCODEC2_INCLUDE_DIR AND LIBCODEC2_LIBRARIES)
+  set(LIBCODEC2_FOUND TRUE)
+  set(LIBCODEC2_INCLUDE_DIRS ${LIBCODEC2_INCLUDE_DIR})
+  set(LIBCODEC2_LIBRARIES ${LIBCODEC2_LIBRARIES} ${LIBCODEC2_LIBRARY})
+  file(READ "${LIBCODEC2_INCLUDE_DIR}/codec2.h" _CODEC2_H_CONTENTS)
+  string(REGEX MATCHALL "CODEC2_MODE[_a-z0-9A-Z]+" CODEC2_MODES "${_CODEC2_H_CONTENTS}")
+  foreach(mode ${CODEC2_MODES})
+    set(LIBCODEC2_HAS_${mode} True)
+  endforeach()
+  if(EXISTS "${LIBCODEC2_INCLUDE_DIR}/freedv_api.h")
+    set(LIBCODEC2_HAS_FREEDV_API True)
+    file(READ "${LIBCODEC2_INCLUDE_DIR}/freedv_api.h" _FREEDV_API_H_CONTENTS)
+    string(REGEX MATCHALL "FREEDV_MODE[_a-z0-9A-Z]+" FREEDV_MODES "${_FREEDV_API_H_CONTENTS}")
+    foreach(mode ${FREEDV_MODES})
+      set(LIBCODEC2_HAS_${mode} True)
+    endforeach()
+  else()
+    set(LIBCODEC2_HAS_FREEDV_API false)
+  endif()
+endif(LIBCODEC2_INCLUDE_DIR AND LIBCODEC2_LIBRARIES)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBCODEC2 DEFAULT_MSG LIBCODEC2_LIBRARIES LIBCODEC2_INCLUDE_DIRS)
+mark_as_advanced(LIBCODEC2_INCLUDE_DIR LIBCODEC2_LIBRARIES)
--- a/gr-vocoder/CMakeLists.txt
+++ b/gr-vocoder/CMakeLists.txt
@@ -89,6 +89,21 @@
 )
 
 ########################################################################
+## CODEC2 Support
+########################################################################
+find_package(Codec2)
+if(LIBCODEC2_FOUND)
+  GR_APPEND_SUBCOMPONENT("codec2")
+  #message(STATUS "libcodec2 modes: ${CODEC2_MODES}")
+  if(LIBCODEC2_HAS_CODEC2_MODE_700)
+    #message(STATUS "libcodec2 has 700bps mode")
+  endif()
+  if (LIBCODEC2_HAS_FREEDV_API)
+    #message(STATUS "libcodec2 had FreeDV api modes: ${FREEDV_MODES}")
+  endif()
+endif(LIBCODEC2_FOUND)
+
+########################################################################
 # Add subdirectories
 ########################################################################
 add_subdirectory(include/gnuradio/vocoder)
--- a/gr-vocoder/examples/CMakeLists.txt
+++ b/gr-vocoder/examples/CMakeLists.txt
@@ -25,7 +25,6 @@
 GR_PYTHON_INSTALL(
     PROGRAMS
     alaw_audio_loopback.py
-    codec2_audio_loopback.py
     cvsd_audio_loopback.py
     g721_audio_loopback.py
     g723_24_audio_loopback.py
@@ -35,3 +34,11 @@
     DESTINATION ${GR_PKG_VOCODER_EXAMPLES_DIR}
     COMPONENT "vocoder_examples"
 )
+if(LIBCODEC2_FOUND)
+  GR_PYTHON_INSTALL(
+    PROGRAMS
+    codec2_audio_loopback.py
+    DESTINATION ${GR_PKG_VOCODER_EXAMPLES_DIR}
+    COMPONENT "vocoder_examples"
+    )
+endif(LIBCODEC2_FOUND)
--- a/gr-vocoder/grc/CMakeLists.txt
+++ b/gr-vocoder/grc/CMakeLists.txt
@@ -21,8 +21,6 @@
     vocoder_alaw_decode_bs.xml
     vocoder_alaw_encode_sb.xml
     vocoder_block_tree.xml
-    vocoder_codec2_decode_ps.xml
-    vocoder_codec2_encode_sp.xml
     vocoder_cvsd_decode_bs.xml
     vocoder_cvsd_decode.xml
     vocoder_cvsd_encode_sb.xml
@@ -40,3 +38,12 @@
     DESTINATION ${GRC_BLOCKS_DIR}
     COMPONENT "vocoder_python"
 )
+
+if(LIBCODEC2_FOUND)
+  install(FILES
+    vocoder_codec2_decode_ps.xml
+    vocoder_codec2_encode_sp.xml
+    DESTINATION ${GRC_BLOCKS_DIR}
+    COMPONENT "vocoder_python"
+    )
+endif(LIBCODEC2_FOUND)
--- a/gr-vocoder/grc/vocoder_codec2_decode_ps.xml
+++ b/gr-vocoder/grc/vocoder_codec2_decode_ps.xml
@@ -39,11 +39,19 @@
 			<name>1200 bps</name>
 			<key>codec2.MODE_1200</key>
 		</option>
+		<option>
+			<name>700 bps</name>
+			<key>codec2.MODE_700</key>
+		</option>
+		<option>
+			<name>700B bps</name>
+			<key>codec2.MODE_700B</key>
+		</option>
 	</param>
 	<sink>
 		<name>in</name>
 		<type>byte</type>
-		<vlen>{ 0: 64, 1: 48, 2: 64, 3: 56, 4: 52, 5: 48 }[$mode]</vlen>
+		<vlen>{ 0: 64, 1: 48, 2: 64, 3: 56, 4: 52, 5: 48, 6: 28, 7: 28 }[$mode]</vlen>
 	</sink>
 	<source>
 		<name>out</name>
--- a/gr-vocoder/grc/vocoder_codec2_encode_sp.xml
+++ b/gr-vocoder/grc/vocoder_codec2_encode_sp.xml
@@ -39,6 +39,14 @@
 			<name>1200 bps</name>
 			<key>codec2.MODE_1200</key>
 		</option>
+		<option>
+			<name>700 bps</name>
+			<key>codec2.MODE_700</key>
+		</option>
+		<option>
+			<name>700B bps</name>
+			<key>codec2.MODE_700B</key>
+		</option>
 	</param>
 	<sink>
 		<name>in</name>
@@ -47,7 +55,7 @@
 	<source>
 		<name>out</name>
 		<type>byte</type>
-		<vlen>{ 0: 64, 1: 48, 2: 64, 3: 56, 4: 52, 5: 48 }[$mode]</vlen>
+		<vlen>{ 0: 64, 1: 48, 2: 64, 3: 56, 4: 52, 5: 48, 6: 28, 7: 28 }[$mode]</vlen>
 	</source>
 </block>
 
--- a/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt
+++ b/gr-vocoder/include/gnuradio/vocoder/CMakeLists.txt
@@ -39,3 +39,13 @@
     DESTINATION ${GR_INCLUDE_DIR}/gnuradio/vocoder
     COMPONENT "vocoder_devel"
 )
+
+if(LIBCODEC2_FOUND)
+install(FILES
+    codec2.h
+    codec2_decode_ps.h
+    codec2_encode_sp.h
+    DESTINATION ${GR_INCLUDE_DIR}/gnuradio/vocoder
+    COMPONENT "vocoder_devel"
+)
+endif(LIBCODEC2_FOUND)
--- a/gr-vocoder/include/gnuradio/vocoder/codec2.h
+++ b/gr-vocoder/include/gnuradio/vocoder/codec2.h
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2014 Free Software Foundation, Inc.
+ * Copyright 2014,2016 Free Software Foundation, Inc.
  *
  * This file is part of GNU Radio
  *
@@ -26,7 +26,7 @@
 #include <gnuradio/vocoder/api.h>
 
 extern "C" {
-#include "../lib/codec2/codec2.h"
+#include <codec2/codec2.h>
 }
 
 namespace gr {
@@ -42,6 +42,12 @@
 	MODE_1400 = CODEC2_MODE_1400,
 	MODE_1300 = CODEC2_MODE_1300,
 	MODE_1200 = CODEC2_MODE_1200,
+#ifdef CODEC2_MODE_700
+	MODE_700 = CODEC2_MODE_700,
+#endif
+#ifdef CODEC2_MODE_700B
+	MODE_700B = CODEC2_MODE_700B,
+#endif
       };
 
     private:
--- a/gr-vocoder/lib/CMakeLists.txt
+++ b/gr-vocoder/lib/CMakeLists.txt
@@ -82,71 +82,6 @@
 mark_as_advanced(LIBGSM_INCLUDE_DIR LIBGSM_LIBRARIES)
 
 ########################################################################
-# Check for system libcodec2 via CMake variable GR_USE_SYSTEM_LIBCODEC2
-#  if undefined, try to find system libgsm library,
-#    but if there is no system library use a local copy.
-#  if defined True, use system libcodec2 if found, otherwise do not
-#     use a local copy.
-#  if defined False, use the local copy
-########################################################################
-if (NOT DEFINED GR_USE_SYSTEM_LIBCODEC2)
-   find_path(LIBCODEC2_INCLUDE_DIR NAMES codec2.h
-    PATHS
-    ${LIBCODEC2_PKG_INCLUDE_DIRS}
-    /usr/include/codec2
-    /usr/include
-  )
-
-  find_library(LIBCODEC2_LIBRARIES NAMES codec2
-    PATHS
-    ${LIBCODEC2_PKG_LIBRARY_DIRS}
-    /usr/lib
-  )
-
- if(LIBCODEC2_INCLUDE_DIR AND LIBCODEC2_LIBRARIES)
-   set(GR_USE_SYSTEM_LIBCODEC2 TRUE CACHE INTERNAL "System libcodec2 found")
-   message(STATUS "Found libcodec2: ${LIBCODEC2_INCLUDE_DIR}, ${LIBCODEC2_LIBRARIES}")
-   set(GR_USE_LOCAL_LIBCODEC2 FALSE)
-   set(GR_USE_SYSTEM_LIBCODEC2 TRUE)
- else(LIBCODEC2_INCLUDE_DIR AND LIBCODEC2_LIBRARIES)
-   set(GR_USE_SYSTEM_LIBCODEC2 FALSE CACHE INTERNAL "System libcodec2 found")
-   message(STATUS "System libcodec2 not found.")
-   set(GR_USE_LOCAL_LIBCODEC2 TRUE)
- endif(LIBCODEC2_INCLUDE_DIR AND LIBCODEC2_LIBRARIES)
-else (NOT DEFINED GR_USE_SYSTEM_LIBCODEC2)
- if (GR_USE_SYSTEM_LIBCODEC2)
-    find_path(LIBCODEC2_INCLUDE_DIR NAMES codec2.h
-    PATHS
-    ${LIBCODEC2_PKG_INCLUDE_DIRS}
-    /usr/include/codec2
-    /usr/include
-  )
-
-  find_library(LIBCODEC2_LIBRARIES NAMES codec2
-    PATHS
-    ${LIBGSM_PKG_LIBRARY_DIRS}
-    /usr/lib
-  )
-
-  if(LIBCODEC2_INCLUDE_DIR AND LIBCODEC2_LIBRARIES)
-    set(GR_USE_SYSTEM_LIBCODEC2 TRUE CACHE INTERNAL "System libcodec2 found")
-    message(STATUS "Found libgsm: ${LIBCODEC2_INCLUDE_DIR}, ${LIBCODEC2_LIBRARIES}")
-    set(GR_USE_LOCAL_LIBCODEC2 FALSE)
-  else(LIBGCODEC2_INCLUDE_DIR AND LIBCODEC2_LIBRARIES)
-    set(GR_USE_SYSTEM_LIBCODEC2 FALSE CACHE INTERNAL "System libcodec2 found")
-    message(STATUS "System libcodec2 not found.")
-    set(GR_USE_LOCAL_LIBCODEC2 FALSE)
-   endif(LIBCODEC2_INCLUDE_DIR AND LIBCODEC2_LIBRARIES)
- else (GR_USE_SYSTEM_LIBCODEC2)
-    set(GR_USE_LOCAL_LIBCODEC2 TRUE)
-    message(STATUS "Using gnuradio local copy of libcodec2.")
- endif (GR_USE_SYSTEM_LIBCODEC2)
-endif (NOT DEFINED GR_USE_SYSTEM_LIBCODEC2)
-
-mark_as_advanced(LIBCODEC2_INCLUDE_DIR LIBCODEC2_LIBRARIES)
-
-
-########################################################################
 # Setup the include and linker paths
 ########################################################################
 include_directories(
@@ -167,9 +102,6 @@
 list(APPEND gr_vocoder_sources
     alaw_decode_bs_impl.cc
     alaw_encode_sb_impl.cc
-    codec2.cc
-    codec2_decode_ps_impl.cc
-    codec2_encode_sp_impl.cc
     cvsd_decode_bs_impl.cc
     cvsd_encode_sb_impl.cc
     g721_decode_bs_impl.cc
@@ -183,6 +115,13 @@
     ulaw_decode_bs_impl.cc
     ulaw_encode_sb_impl.cc
 )
+if(LIBCODEC2_FOUND)
+  list(APPEND gr_vocoder_sources
+    codec2.cc
+    codec2_decode_ps_impl.cc
+    codec2_encode_sp_impl.cc
+    )
+endif(LIBCODEC2_FOUND)
 
 #Add Windows DLL resource file if using MSVC
 if(MSVC)
@@ -203,10 +142,6 @@
 ########################################################################
 GR_INCLUDE_SUBDIRECTORY(g7xx)
 
-if(GR_USE_LOCAL_LIBCODEC2)
- GR_INCLUDE_SUBDIRECTORY(codec2)
-endif(GR_USE_LOCAL_LIBCODEC2)
-
 if(GR_USE_LOCAL_LIBGSM)
  GR_INCLUDE_SUBDIRECTORY(gsm)
 endif(GR_USE_LOCAL_LIBGSM)
@@ -216,9 +151,9 @@
     ${Boost_LIBRARIES}
 )
 
-if(GR_USE_SYSTEM_LIBCODEC2)
+if(LIBCODEC2_LIBRARIES)
   list(APPEND vocoder_libs ${LIBCODEC2_LIBRARIES})
-endif(GR_USE_SYSTEM_LIBCODEC2)
+endif(LIBCODEC2_LIBRARIES)
 
 if(GR_USE_SYSTEM_LIBGSM)
   list(APPEND vocoder_libs ${LIBGSM_LIBRARIES})
--- a/gr-vocoder/python/vocoder/CMakeLists.txt
+++ b/gr-vocoder/python/vocoder/CMakeLists.txt
@@ -47,7 +47,20 @@
     )
 
   include(GrTest)
-  file(GLOB py_qa_test_files "qa_*.py")
+  list(APPEND py_qa_test_files
+    qa_alaw_vocoder.py
+    qa_cvsd_vocoder.py
+    qa_g721_vocoder.py
+    qa_g723_24_vocoder.py
+    qa_g723_40_vocoder.py
+    qa_gsm_full_rate.py
+    qa_ulaw_vocoder.py
+    )
+  if(LIBCODEC2_FOUND)
+    list(APPEND py_qa_test_files
+      qa_codec2_vocoder.py
+      )
+  endif()
   foreach(py_qa_test_file ${py_qa_test_files})
     get_filename_component(py_qa_test_name ${py_qa_test_file} NAME_WE)
     GR_ADD_TEST(${py_qa_test_name} ${QA_PYTHON_EXECUTABLE} ${PYTHON_DASH_B} ${py_qa_test_file})
--- a/gr-vocoder/swig/CMakeLists.txt
+++ b/gr-vocoder/swig/CMakeLists.txt
@@ -33,6 +33,10 @@
   list(APPEND GR_SWIG_FLAGS "-DGR_CTRLPORT")
 endif(ENABLE_GR_CTRLPORT)
 
+if(LIBCODEC2_FOUND)
+  list(APPEND GR_SWIG_FLAGS "-DLIBCODEC2_FOUND")
+endif(LIBCODEC2_FOUND)
+
 set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/vocoder_swig_doc.i)
 set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include/gnuradio/vocoder)
 set(GR_SWIG_DOCS_TARGET_DEPS runtime_swig_swig_doc)
--- a/gr-vocoder/swig/vocoder_swig.i
+++ b/gr-vocoder/swig/vocoder_swig.i
@@ -30,9 +30,6 @@
 %{
 #include "gnuradio/vocoder/alaw_decode_bs.h"
 #include "gnuradio/vocoder/alaw_encode_sb.h"
-#include "gnuradio/vocoder/codec2.h"
-#include "gnuradio/vocoder/codec2_decode_ps.h"
-#include "gnuradio/vocoder/codec2_encode_sp.h"
 #include "gnuradio/vocoder/cvsd_decode_bs.h"
 #include "gnuradio/vocoder/cvsd_encode_sb.h"
 #include "gnuradio/vocoder/g721_decode_bs.h"
@@ -49,9 +46,6 @@
 
 %include "gnuradio/vocoder/alaw_decode_bs.h"
 %include "gnuradio/vocoder/alaw_encode_sb.h"
-%include "gnuradio/vocoder/codec2.h"
-%include "gnuradio/vocoder/codec2_decode_ps.h"
-%include "gnuradio/vocoder/codec2_encode_sp.h"
 %include "gnuradio/vocoder/cvsd_decode_bs.h"
 %include "gnuradio/vocoder/cvsd_encode_sb.h"
 %include "gnuradio/vocoder/g721_decode_bs.h"
@@ -67,8 +61,6 @@
 
 GR_SWIG_BLOCK_MAGIC2(vocoder, alaw_decode_bs);
 GR_SWIG_BLOCK_MAGIC2(vocoder, alaw_encode_sb);
-GR_SWIG_BLOCK_MAGIC2(vocoder, codec2_decode_ps);
-GR_SWIG_BLOCK_MAGIC2(vocoder, codec2_encode_sp);
 GR_SWIG_BLOCK_MAGIC2(vocoder, cvsd_decode_bs);
 GR_SWIG_BLOCK_MAGIC2(vocoder, cvsd_encode_sb);
 GR_SWIG_BLOCK_MAGIC2(vocoder, g721_decode_bs);
@@ -81,3 +73,20 @@
 GR_SWIG_BLOCK_MAGIC2(vocoder, gsm_fr_encode_sp);
 GR_SWIG_BLOCK_MAGIC2(vocoder, ulaw_decode_bs);
 GR_SWIG_BLOCK_MAGIC2(vocoder, ulaw_encode_sb);
+
+#ifdef LIBCODEC2_FOUND
+%{
+#include <codec2/codec2.h>
+#include "gnuradio/vocoder/codec2.h"
+#include "gnuradio/vocoder/codec2_decode_ps.h"
+#include "gnuradio/vocoder/codec2_encode_sp.h"
+%}
+
+%include <codec2/codec2.h>
+%include "gnuradio/vocoder/codec2.h"
+%include "gnuradio/vocoder/codec2_decode_ps.h"
+%include "gnuradio/vocoder/codec2_encode_sp.h"
+
+GR_SWIG_BLOCK_MAGIC2(vocoder, codec2_decode_ps);
+GR_SWIG_BLOCK_MAGIC2(vocoder, codec2_encode_sp);
+#endif
