ref: c08494b8ad75e0e9f964c3257a88fc82138db631
parent: 08cd2f3d04583fc45a3cf2852a940f27adfafede
author: robs <robs>
date: Tue Dec 25 16:34:27 EST 2007
Simple example of using SoX libraries
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -48,9 +48,12 @@
getopt soxio
getopt1 soxstdint
)
+set(optional_libs /usr/local/lib/libsndfile.so ${optional_libs})
add_executable(${PROJECT_NAME} ${PROJECT_NAME}.c)
target_link_libraries(${PROJECT_NAME} lib${PROJECT_NAME} lpc10 ${optional_libs})
add_executable(sox_sample_test sox_sample_test.c)
+add_executable(example1 example1.c)
+target_link_libraries(example1 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
@@ -12,11 +12,14 @@
# SoX - the application #
#########################
-bin_PROGRAMS = sox
+bin_PROGRAMS = sox sox_sample_test example1
lib_LTLIBRARIES = libsox.la libsfx.la
include_HEADERS = sox.h soxstdint.h
sox_SOURCES = sox.c
sox_LDADD = libsox.la libsfx.la
+example1_SOURCES = example1.c
+example1_LDADD = libsox.la libsfx.la
+sox_sample_test_SOURCES = sox_sample_test.c
#############################################
# libsox Dynamic Libraries for File Formats #
@@ -282,9 +285,9 @@
#end !HAVE_LIBLTDL
endif
-EXTRA_DIST = tests.sh testall.sh tests.bat testall.bat monkey.au monkey.wav sox_sample_test.c amr-wb-test CMakeLists.txt soxstdint.h.cmake soxconfig.h.cmake
+EXTRA_DIST = tests.sh testall.sh tests.bat testall.bat monkey.au monkey.wav sox_sample_test.c amr-wb-test CMakeLists.txt soxstdint.h.cmake soxconfig.h.cmake example1.c
-all: sox$(EXEEXT) play rec
+all: sox$(EXEEXT) play rec sox_sample_test example1
play rec: sox$(EXEEXT)
./sox --help > /dev/null
@@ -298,6 +301,7 @@
clean-local:
$(RM) play rec
$(RM) sox_sample_test
+ $(RM) example1
distclean-local:
$(RM) soxstdint.h
--- a/src/effects.c
+++ b/src/effects.c
@@ -92,6 +92,13 @@
/* Effects chain: */
+sox_effects_chain_t * sox_create_effects_chain(void)
+{
+ sox_effects_chain_t * result = xcalloc(1, sizeof(sox_effects_chain_t));
+ result->global_info = sox_effects_globals;
+ return result;
+}
+
/* Effect can call in start() or flow() to set minimum input size to flow() */
int sox_effect_set_imin(sox_effect_t * effp, sox_size_t imin)
{
@@ -364,8 +371,17 @@
/* Remove all effects from the chain */
void sox_delete_effects(sox_effects_chain_t * chain)
{
- while (chain->length)
- free(chain->effects[--chain->length]);
+ sox_size_t e, clips;
+
+ for (e = 0; e < chain->length; ++e) {
+ sox_effect_t * effp = chain->effects[e];
+ if ((clips = sox_stop_effect(chain, e)) != 0)
+ sox_warn("%s clipped %u samples; decrease volume?",
+ chain->effects[e][0].handler.name, clips);
+ effp->handler.kill(effp);
+ free(chain->effects[e]);
+ }
+ chain->length = 0;
}
--- /dev/null
+++ b/src/example1.c
@@ -1,0 +1,107 @@
+/*
+ * Simple example of using SoX libraries
+ *
+ * Copyright (c) 2007 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, Fifth
+ * Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
+ */
+
+#include "sox.h"
+#include <stdio.h>
+#ifdef NDEBUG /* N.B. assert used with active statements so enable always */
+#undef NDEBUG
+#endif
+#include <assert.h>
+
+static sox_format_t * in, * out;
+
+static int input_drain(sox_effect_t *effp, sox_sample_t * obuf, sox_size_t * osamp)
+{
+ *osamp -= *osamp % effp->outinfo.channels;
+ *osamp = sox_read(in, obuf, *osamp);
+ *osamp -= *osamp % effp->outinfo.channels;
+ if (!*osamp && in->sox_errno)
+ fprintf(stderr, "%s: %s\n", in->filename, in->sox_errstr);
+ return *osamp? SOX_SUCCESS : SOX_EOF;
+}
+
+static int output_flow(sox_effect_t *effp UNUSED, sox_sample_t const * ibuf,
+ sox_sample_t * obuf UNUSED, sox_size_t * isamp, sox_size_t * osamp)
+{
+ size_t len;
+ for (*osamp = *isamp; *osamp; ibuf += len, *osamp -= len) {
+ len = sox_write(out, ibuf, *osamp);
+ if (!len || out->sox_errno) {
+ fprintf(stderr, "%s: %s\n", out->filename, out->sox_errstr);
+ return SOX_EOF;
+ }
+ }
+ return SOX_SUCCESS;
+}
+
+static sox_effect_handler_t const * input_handler(void)
+{
+ static sox_effect_handler_t handler = {
+ "input", NULL, SOX_EFF_MCHAN, NULL, NULL, NULL, input_drain, NULL, NULL
+ };
+ return &handler;
+}
+
+static sox_effect_handler_t const * output_handler(void)
+{
+ static sox_effect_handler_t handler = {
+ "output", NULL, SOX_EFF_MCHAN, NULL, NULL, output_flow, NULL, NULL, NULL
+ };
+ return &handler;
+}
+
+/*
+ * Reads input file, applies vol & reverb effects, stores in output file.
+ * E.g. example1 monkey.au monkey.aiff
+ */
+int main(int argc, char * argv[])
+{
+ sox_effects_chain_t * chain = sox_create_effects_chain();
+ sox_effect_t e;
+ char * vol[] = {"3dB"};
+
+ assert(argc == 3);
+ assert(sox_format_init() == SOX_SUCCESS);
+
+ assert(in = sox_open_read(argv[1], NULL, NULL));
+ sox_create_effect(&e, input_handler());
+ assert(sox_add_effect(chain, &e, &in->signal, &in->signal) == SOX_SUCCESS);
+
+ sox_create_effect(&e, sox_find_effect("vol"));
+ assert(e.handler.getopts(&e, 1, vol) == SOX_SUCCESS);
+ assert(sox_add_effect(chain, &e, &in->signal, &in->signal) == SOX_SUCCESS);
+
+ sox_create_effect(&e, sox_find_effect("reverb"));
+ assert(e.handler.getopts(&e, 0, NULL) == SOX_SUCCESS);
+ assert(sox_add_effect(chain, &e, &in->signal, &in->signal) == SOX_SUCCESS);
+
+ assert(out = sox_open_write(NULL, argv[2], &in->signal, NULL, NULL, 0, NULL, 0));
+ sox_create_effect(&e, output_handler());
+ assert(sox_add_effect(chain, &e, &in->signal, &in->signal) == SOX_SUCCESS);
+
+ assert(sox_flow_effects(chain, NULL) == SOX_SUCCESS);
+
+ sox_close(out);
+ sox_delete_effects(chain);
+ sox_close(in);
+ sox_format_quit();
+ free(chain);
+ return 0;
+}
--- a/src/sox.c
+++ b/src/sox.c
@@ -17,7 +17,7 @@
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this library. If not, write to the Free Software
+ * along with this program. If not, write to the Free Software
* Foundation, Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301,
* USA.
*/
@@ -325,7 +325,6 @@
for (i = 0; i < input_count; i++) {
if (files[i]->ft) {
sox_close(files[i]->ft);
- free(files[i]->ft);
}
free(files[i]);
}
@@ -343,7 +342,6 @@
/* Assumption: we can unlink a file before sox_closing it. */
sox_close(ofile->ft);
- free(ofile->ft);
}
free(ofile);
}
@@ -708,13 +706,9 @@
if (combine_method == sox_sequence) do {
if (ofile->ft)
sox_close(ofile->ft);
- free(ofile->ft);
} while (process() != SOX_EOF && !user_abort && current_input < input_count);
else process();
- while (nuser_effects--)
- user_efftab[nuser_effects].handler.kill(&user_efftab[nuser_effects]);
-
for (i = 0; i < file_count; ++i)
if (files[i]->ft->clips != 0)
sox_warn(i < input_count?"%s: input clipped %u samples" :
@@ -1147,12 +1141,29 @@
files[i]->ft->signal.rate == files[i - 1]->ft->signal.rate;
}
+static void display_error(sox_format_t * ft)
+{
+ static char const * const sox_strerror[] = {
+ "Invalid Audio Header",
+ "Unsupported data format",
+ "Unsupported rate for format",
+ "Can't alloc memory",
+ "Operation not permitted",
+ "Operation not supported",
+ "Invalid argument",
+ "Unsupported file format",
+ };
+ sox_fail("%s: %s (%s)", ft->filename, ft->sox_errstr,
+ ft->sox_errno < SOX_EHDR?
+ strerror(ft->sox_errno) : sox_strerror[ft->sox_errno - SOX_EHDR]);
+}
+
static sox_size_t sox_read_wide(sox_format_t * ft, sox_sample_t * buf, sox_size_t max)
{
sox_size_t len = max / combiner.channels;
len = sox_read(ft, buf, len * ft->signal.channels) / ft->signal.channels;
if (!len && ft->sox_errno)
- sox_fail("%s: %s (%s)", ft->filename, ft->sox_errstr, strerror(ft->sox_errno));
+ display_error(ft);
return len;
}
@@ -1439,16 +1450,6 @@
return user_abort? SOX_EOF : SOX_SUCCESS;
}
-static void sox_stop_effects(sox_effects_chain_t * chain)
-{
- sox_size_t e, clips;
-
- for (e = 0; e < chain->length; ++e)
- if ((clips = sox_stop_effect(chain, e)) != 0)
- sox_warn("%s clipped %u samples; decrease volume?",
- chain->effects[e][0].handler.name, clips);
-}
-
/*
* Process: Input(s) -> Balancing -> Combiner -> Effects -> Output
*/
@@ -1530,7 +1531,6 @@
flowstatus = sox_flow_effects(&ofile_effects_chain, update_status);
- sox_stop_effects(&ofile_effects_chain);
sox_delete_effects(&ofile_effects_chain);
return flowstatus;
}
--- a/src/sox.h
+++ b/src/sox.h
@@ -433,6 +433,7 @@
struct sox_effects_chain;
typedef struct sox_effects_chain sox_effects_chain_t;
+sox_effects_chain_t * sox_create_effects_chain(void);
int sox_add_effect(sox_effects_chain_t *, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out);
int sox_flow_effects(sox_effects_chain_t *, int (* callback)(sox_bool all_done));
--- a/src/soxio.c
+++ b/src/soxio.c
@@ -15,8 +15,18 @@
#include <ltdl.h>
#endif
-sox_globals_t sox_globals = {2, 8192, NULL, NULL, NULL, NULL};
+static void output_message(unsigned level, const char *filename, const char *fmt, va_list ap);
+sox_globals_t sox_globals = {2, 8192, NULL, NULL, output_message, NULL};
+
+static void output_message(unsigned level, const char *filename, const char *fmt, va_list ap)
+{
+ if (sox_globals.verbosity >= level) {
+ sox_output_message(stderr, filename, fmt, ap);
+ fprintf(stderr, "\n");
+ }
+}
+
/* Plugins */
#ifdef HAVE_LIBLTDL
@@ -179,6 +189,10 @@
{
sox_format_t * ft = xcalloc(sizeof(*ft), 1);
+ ft->signal.reverse_bytes =
+ ft->signal.reverse_nibbles =
+ ft->signal.reverse_bits = SOX_OPTION_DEFAULT;
+
ft->filename = xstrdup(path);
/* Let auto type do the work if user is not overriding. */
@@ -307,7 +321,7 @@
else {
struct stat st;
if (!stat(ft->filename, &st) && (st.st_mode & S_IFMT) == S_IFREG &&
- !overwrite_permitted(ft->filename)) {
+ (overwrite_permitted && !overwrite_permitted(ft->filename))) {
sox_fail("Permission to overwrite '%s' denied", ft->filename);
goto output_error;
}
@@ -513,6 +527,7 @@
if (ft->mode == 'w')
free(ft->comment);
+ free(ft);
return rc;
}