ref: 1ae149575634c0639342e96b0353e010d3fe621f
parent: 075f3b16097b7e12791ddcb236a5b3d0ceb088c0
author: robs <robs>
date: Sat Sep 12 18:32:09 EDT 2009
file IO in memory
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,6 +52,7 @@
check_include_files("termios.h" HAVE_TERMIOS_H)
check_include_files("unistd.h" HAVE_UNISTD_H)
+check_function_exists("fmemopen" HAVE_FMEMOPEN)
check_function_exists("fseeko" HAVE_FSEEKO)
check_function_exists("gettimeofday" HAVE_GETTIMEOFDAY)
check_function_exists("mkstemp" HAVE_MKSTEMP)
--- a/ChangeLog
+++ b/ChangeLog
@@ -29,7 +29,8 @@
LibSoX interface changes:
- None.
+ o Added new variants of sox_open to allow read/write from/to memory
+ buffers (in POSIX 200x environment); see example5.c (robs)
File formats:
--- a/configure.ac
+++ b/configure.ac
@@ -156,7 +156,7 @@
AC_CHECK_HEADERS(fcntl.h unistd.h byteswap.h sys/time.h sys/timeb.h sys/types.h sys/utsname.h termios.h glob.h)
dnl Checks for library functions.
-AC_CHECK_FUNCS(strcasecmp strdup popen vsnprintf gettimeofday mkstemp)
+AC_CHECK_FUNCS(strcasecmp strdup popen vsnprintf gettimeofday mkstemp fmemopen)
dnl Check if math library is needed.
AC_CHECK_FUNC(pow)
--- a/src/.cvsignore
+++ b/src/.cvsignore
@@ -1,6 +1,6 @@
Makefile Makefile.in
sox_sample_test
-example0 example1 example2 example3 example4
+example?
soxconfig.h.in soxconfig.h soxstdint.h
.deps
stamp-h1
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -78,6 +78,8 @@
target_link_libraries(example3 lib${PROJECT_NAME} lpc10 ${optional_libs})
add_executable(example4 example4.c)
target_link_libraries(example4 lib${PROJECT_NAME} lpc10 ${optional_libs})
+add_executable(example5 example5.c)
+target_link_libraries(example5 lib${PROJECT_NAME} lpc10 ${optional_libs})
find_program(LN ln)
if (LN)
add_custom_target(rec ALL ${LN} -sf sox rec DEPENDS sox)
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -30,7 +30,7 @@
#########################
bin_PROGRAMS = sox
-EXTRA_PROGRAMS = example0 example1 example2 example3 example4 sox_sample_test
+EXTRA_PROGRAMS = example0 example1 example2 example3 example4 example5 sox_sample_test
lib_LTLIBRARIES = libsox.la
include_HEADERS = sox.h
nodist_include_HEADERS = soxstdint.h
@@ -41,6 +41,7 @@
example2_SOURCES = example2.c
example3_SOURCES = example3.c
example4_SOURCES = example4.c
+example5_SOURCES = example5.c
sox_sample_test_SOURCES = sox_sample_test.c sox_sample_test.h
@@ -123,12 +124,13 @@
example2_LDADD = ${sox_LDADD}
example3_LDADD = ${sox_LDADD}
example4_LDADD = ${sox_LDADD}
+example5_LDADD = ${sox_LDADD}
EXTRA_DIST = monkey.au monkey.wav optional-fmts.in \
CMakeLists.txt soxstdint.h.cmake soxconfig.h.cmake \
tests.sh testall.sh tests.bat testall.bat test-comments
-all: sox$(EXEEXT) play rec soxi sox_sample_test$(EXEEXT) example0$(EXEEXT) example1$(EXEEXT) example2$(EXEEXT) example3$(EXEEXT) example4$(EXEEXT)
+all: sox$(EXEEXT) play rec soxi sox_sample_test$(EXEEXT) example0$(EXEEXT) example1$(EXEEXT) example2$(EXEEXT) example3$(EXEEXT) example4$(EXEEXT) example5$(EXEEXT)
play rec: sox$(EXEEXT)
if test "$(PLAYRECLINKS)" = "yes"; then \
@@ -159,7 +161,7 @@
clean-local:
$(RM) play rec soxi
$(RM) sox_sample_test$(EXEEXT)
- $(RM) example0$(EXEEXT) example1$(EXEEXT) example2$(EXEEXT) example3$(EXEEXT) example4$(EXEEXT)
+ $(RM) example0$(EXEEXT) example1$(EXEEXT) example2$(EXEEXT) example3$(EXEEXT) example4$(EXEEXT) example5$(EXEEXT)
distclean-local:
$(RM) soxstdint.h
@@ -173,6 +175,7 @@
$(example2_SOURCES) \
$(example3_SOURCES) \
$(example4_SOURCES) \
+ $(example5_SOURCES) \
$(sox_sample_test_SOURCES) \
$(libsox_la_SOURCES)
--- /dev/null
+++ b/src/example5.c
@@ -1,0 +1,83 @@
+/* Simple example of using SoX libraries
+ *
+ * Copyright (c) 2009 robs@users.sourceforge.net
+ *
+ * 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 2 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef NDEBUG /* N.B. assert used with active statements so enable always. */
+#undef NDEBUG /* Must undef above assert.h or other that might include it. */
+#endif
+
+#include "sox.h"
+#include "util.h"
+#include <stdio.h>
+#include <assert.h>
+
+/* Example of reading and writing audio files stored in memory buffers
+ * rather than actual files.
+ *
+ * Usage: example5 input output
+ */
+
+/* Uncomment following line for fixed instead of malloc'd buffer: */
+/*#define FIXED_BUFFER */
+
+#if defined FIXED_BUFFER
+#define buffer_size 123456
+static char buffer[buffer_size];
+#endif
+
+int main(int argc, char * argv[])
+{
+ static sox_format_t * in, * out; /* input and output files */
+ #define MAX_SAMPLES (size_t)2048
+ sox_sample_t samples[MAX_SAMPLES]; /* Temporary store whilst copying. */
+#if !defined FIXED_BUFFER
+ char * buffer;
+ size_t buffer_size;
+#endif
+ size_t number_read;
+
+ assert(argc == 3);
+
+ /* All libSoX applications must start by initialising the SoX library */
+ assert(sox_init() == SOX_SUCCESS);
+
+ /* Open the input file (with default parameters) */
+ assert(in = sox_open_read(argv[1], NULL, NULL, NULL));
+#if defined FIXED_BUFFER
+ assert(out = sox_open_mem_write(buffer, buffer_size, &in->signal, NULL, "sox", NULL));
+#else
+ assert(out = sox_open_memstream_write(&buffer, &buffer_size, &in->signal, NULL, "sox", NULL));
+#endif
+ while ((number_read = sox_read(in, samples, MAX_SAMPLES)))
+ assert(sox_write(out, samples, number_read) == number_read);
+ sox_close(out);
+ sox_close(in);
+
+ assert(in = sox_open_mem_read(buffer, buffer_size, NULL, NULL, NULL));
+ assert(out = sox_open_write(argv[2], &in->signal, NULL, NULL, NULL, NULL));
+ while ((number_read = sox_read(in, samples, MAX_SAMPLES)))
+ assert(sox_write(out, samples, number_read) == number_read);
+ sox_close(out);
+ sox_close(in);
+#if !defined FIXED_BUFFER
+ free(buffer);
+#endif
+
+ sox_quit();
+ return 0;
+}
--- a/src/formats.c
+++ b/src/formats.c
@@ -412,8 +412,10 @@
#endif
}
-sox_format_t * sox_open_read(
+static sox_format_t * open_read(
char const * path,
+ void * buffer,
+ size_t buffer_size,
sox_signalinfo_t const * signal,
sox_encodinginfo_t const * encoding,
char const * filetype)
@@ -444,7 +446,11 @@
ft->fp = stdin;
}
else {
- ft->fp = xfopen(path, "rb", &ft->io_type);
+ ft->fp =
+#ifdef HAVE_FMEMOPEN
+ buffer? fmemopen(buffer, buffer_size, "rb") :
+#endif
+ xfopen(path, "rb", &ft->io_type);
type = io_types[ft->io_type];
if (ft->fp == NULL) {
lsx_fail("can't open input %s `%s': %s", type, path, strerror(errno));
@@ -554,6 +560,25 @@
return NULL;
}
+sox_format_t * sox_open_read(
+ char const * path,
+ sox_signalinfo_t const * signal,
+ sox_encodinginfo_t const * encoding,
+ char const * filetype)
+{
+ return open_read(path, NULL, 0, signal, encoding, filetype);
+}
+
+sox_format_t * sox_open_mem_read(
+ void * buffer,
+ size_t buffer_size,
+ sox_signalinfo_t const * signal,
+ sox_encodinginfo_t const * encoding,
+ char const * filetype)
+{
+ return open_read("", buffer, buffer_size, signal,encoding,filetype);
+}
+
sox_bool sox_format_supports_encoding(
char const * path,
char const * filetype,
@@ -776,8 +801,12 @@
return handler;
}
-sox_format_t * sox_open_write(
+static sox_format_t * open_write(
char const * path,
+ void * buffer,
+ size_t buffer_size,
+ char * * buffer_ptr,
+ size_t * buffer_size_ptr,
sox_signalinfo_t const * signal,
sox_encodinginfo_t const * encoding,
char const * filetype,
@@ -814,7 +843,13 @@
lsx_fail("permission to overwrite `%s' denied", path);
goto error;
}
- if ((ft->fp = fopen(path, "w+b")) == NULL) {
+ ft->fp =
+#ifdef HAVE_FMEMOPEN
+ buffer? fmemopen(buffer, buffer_size, "w+b") :
+ buffer_ptr? open_memstream(buffer_ptr, buffer_size_ptr) :
+#endif
+ fopen(path, "w+b");
+ if (ft->fp == NULL) {
lsx_fail("can't open output file `%s': %s", path, strerror(errno));
goto error;
}
@@ -884,6 +919,39 @@
free(ft->filetype);
free(ft);
return NULL;
+}
+
+sox_format_t * sox_open_write(
+ char const * path,
+ sox_signalinfo_t const * signal,
+ sox_encodinginfo_t const * encoding,
+ char const * filetype,
+ sox_oob_t const * oob,
+ sox_bool (*overwrite_permitted)(const char *filename))
+{
+ return open_write(path, NULL, 0, NULL, NULL, signal, encoding, filetype, oob, overwrite_permitted);
+}
+
+sox_format_t * sox_open_mem_write(
+ void * buffer,
+ size_t buffer_size,
+ sox_signalinfo_t const * signal,
+ sox_encodinginfo_t const * encoding,
+ char const * filetype,
+ sox_oob_t const * oob)
+{
+ return open_write("", buffer, buffer_size, NULL, NULL, signal, encoding, filetype, oob, NULL);
+}
+
+sox_format_t * sox_open_memstream_write(
+ char * * buffer_ptr,
+ size_t * buffer_size_ptr,
+ sox_signalinfo_t const * signal,
+ sox_encodinginfo_t const * encoding,
+ char const * filetype,
+ sox_oob_t const * oob)
+{
+ return open_write("", NULL, 0, buffer_ptr, buffer_size_ptr, signal, encoding, filetype, oob, NULL);
}
size_t sox_read(sox_format_t * ft, sox_sample_t * buf, size_t len)
--- a/src/sox.h
+++ b/src/sox.h
@@ -412,6 +412,12 @@
sox_signalinfo_t const * signal,
sox_encodinginfo_t const * encoding,
char const * filetype);
+sox_format_t * sox_open_mem_read(
+ void * buffer,
+ size_t buffer_size,
+ sox_signalinfo_t const * signal,
+ sox_encodinginfo_t const * encoding,
+ char const * filetype);
sox_bool sox_format_supports_encoding(
char const * path,
char const * filetype,
@@ -427,6 +433,20 @@
char const * filetype,
sox_oob_t const * oob,
sox_bool (*overwrite_permitted)(const char *filename));
+sox_format_t * sox_open_mem_write(
+ void * buffer,
+ size_t buffer_size,
+ sox_signalinfo_t const * signal,
+ sox_encodinginfo_t const * encoding,
+ char const * filetype,
+ sox_oob_t const * oob);
+sox_format_t * sox_open_memstream_write(
+ char * * buffer_ptr,
+ size_t * buffer_size_ptr,
+ sox_signalinfo_t const * signal,
+ sox_encodinginfo_t const * encoding,
+ char const * filetype,
+ sox_oob_t const * oob);
size_t sox_read(sox_format_t * ft, sox_sample_t *buf, size_t len);
size_t sox_write(sox_format_t * ft, const sox_sample_t *buf, size_t len);
int sox_close(sox_format_t * ft);
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -14,6 +14,9 @@
#define SOX_I_H
#include "soxomp.h" /* Make this 1st in list (for soxconfig) */
+#if defined HAVE_FMEMOPEN
+#define _GNU_SOURCE
+#endif
#include "sox.h"
#include "util.h"
--- a/src/soxconfig.h.cmake
+++ b/src/soxconfig.h.cmake
@@ -10,6 +10,7 @@
#cmakedefine HAVE_COREAUDIO 1
#cmakedefine HAVE_FFMPEG 1
#cmakedefine HAVE_FLAC 1
+#cmakedefine HAVE_FMEMOPEN 1
#cmakedefine HAVE_FSEEKO 1
#cmakedefine HAVE_GETTIMEOFDAY 1
#cmakedefine HAVE_GLOB_H 1