changeset 32195:9cb43336c3b3

audiowrite: Allow writing mp3 through libsndfile API (bug #64388). * m4/acinclude.m4 (OCTAVE_CHECK_LIB_SNDFILE_FORMATS): New function that checks if libsndfile is able to write specific audio formats (currently MPEG audio formats, including mp3). * configure.ac: Call OCTAVE_CHECK_LIB_SNDFILE_FORMATS if libsndfile can be used. * libinterp/dldfcn/audioread.cc (extension_to_format): Add m1a lookup. (audiowrite): For file extenstions .mp1, .mp2, or .mp3, explicitly assign corresponding format and MPEG layer. * etc/NEWS.9.md: Add note about new feature.
author John Donoghue <john.donoghue@ieee.org>
date Thu, 06 Jul 2023 11:56:37 -0400
parents b9cabe8a9fb0
children 4b48ab05ba02
files configure.ac etc/NEWS.9.md libinterp/dldfcn/audioread.cc m4/acinclude.m4
diffstat 4 files changed, 36 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Sat Jul 15 10:52:57 2023 +0200
+++ b/configure.ac	Thu Jul 06 11:56:37 2023 -0400
@@ -1665,7 +1665,8 @@
   [], [don't use sndfile library, disable audio file I/O],
   [warn_sndfile=
    OCTAVE_CHECK_LIB_SNDFILE_OK(
-    [AC_DEFINE(HAVE_SNDFILE, 1, [Define to 1 if sndfile is available.])],
+    [AC_DEFINE(HAVE_SNDFILE, 1, [Define to 1 if sndfile is available.])
+     OCTAVE_CHECK_LIB_SNDFILE_FORMATS],
     [warn_sndfile="sndfile library found, but does not seem to work properly; disabling audio file I/O functions"])])
 
 ### Check for PortAudio library.
--- a/etc/NEWS.9.md	Sat Jul 15 10:52:57 2023 +0200
+++ b/etc/NEWS.9.md	Thu Jul 06 11:56:37 2023 -0400
@@ -43,6 +43,9 @@
 
 - The `perms` function has been made faster.
 
+- The `audiowrite` function now supports writing to MPEG audio formats --
+including MP3 -- if the `sndfile` library supports it.
+
 ### Graphical User Interface
 
 ### Graphics backend
--- a/libinterp/dldfcn/audioread.cc	Sat Jul 15 10:52:57 2023 +0200
+++ b/libinterp/dldfcn/audioread.cc	Thu Jul 06 11:56:37 2023 -0400
@@ -229,6 +229,9 @@
       table["ogg"] = SF_FORMAT_OGG;
       table["mpc2k"] = SF_FORMAT_MPC2K;
       table["rf64"] = SF_FORMAT_RF64;
+#if defined (HAVE_LIB_SNDFILE_FORMAT_MP3)
+      table["m1a"] = SF_FORMAT_MPEG;
+#endif
 
       initialized = true;
     }
@@ -343,6 +346,14 @@
       // problem and produces valid files.
       chunk_size = 0x100000;
     }
+#if defined (HAVE_LIB_SNDFILE_FORMAT_MP3)
+  else if (ext == "mp1")
+    info.format = SF_FORMAT_MPEG|SF_FORMAT_MPEG_LAYER_I;
+  else if (ext == "mp2")
+    info.format = SF_FORMAT_MPEG|SF_FORMAT_MPEG_LAYER_II;
+  else if (ext == "mp3")
+    info.format = SF_FORMAT_MPEG|SF_FORMAT_MPEG_LAYER_III;
+#endif
   else
     info.format = SF_FORMAT_PCM_16;
 
--- a/m4/acinclude.m4	Sat Jul 15 10:52:57 2023 +0200
+++ b/m4/acinclude.m4	Thu Jul 06 11:56:37 2023 -0400
@@ -1584,6 +1584,26 @@
     :
   fi
 ])
+
+dnl
+dnl Check for support of some specific formats in sndfile library 
+dnl
+AC_DEFUN([OCTAVE_CHECK_LIB_SNDFILE_FORMATS], [
+  AC_CACHE_CHECK([whether sndfile library supports mp3],
+    [octave_cv_lib_sndfile_format_mp3],
+    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+        #include <sndfile.h>
+        ]], [[
+        int x = SF_FORMAT_MPEG;
+      ]])],
+      octave_cv_lib_sndfile_format_mp3=yes,
+      octave_cv_lib_sndfile_format_mp3=no)
+  ])
+  if test $octave_cv_lib_sndfile_format_mp3 = yes; then
+    AC_DEFINE(HAVE_LIB_SNDFILE_FORMAT_MP3, 1,
+      [Define to 1 if libsndfile supports mp3.])
+  fi
+])
 dnl
 dnl Check whether new API is used with QHelpIndexWidget.
 dnl Under new API, QHelpIndexWidget emits documentActivates.