X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/1059e1cc0c2ecfa237406949aa26155b6a5b9154..66f23d4fabf89ad09adbd4dfc15ac6b5b2b7da83:/interpreter/lib/src/libsndfile-1.0.25/programs/sndfile-interleave.c diff --git a/interpreter/lib/src/libsndfile-1.0.25/programs/sndfile-interleave.c b/interpreter/lib/src/libsndfile-1.0.25/programs/sndfile-interleave.c new file mode 100644 index 0000000..24d6b9d --- /dev/null +++ b/interpreter/lib/src/libsndfile-1.0.25/programs/sndfile-interleave.c @@ -0,0 +1,202 @@ +/* +** Copyright (C) 2009-2011 Erik de Castro Lopo +** +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the author nor the names of any contributors may be used +** to endorse or promote products derived from this software without +** specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include + +#include "common.h" + +#define BUFFER_LEN 4096 +#define MAX_INPUTS 16 + + +typedef struct +{ SNDFILE * infile [MAX_INPUTS] ; + SNDFILE * outfile ; + + union + { double d [BUFFER_LEN] ; + int i [BUFFER_LEN] ; + } din ; + + union + + { double d [MAX_INPUTS * BUFFER_LEN] ; + int i [MAX_INPUTS * BUFFER_LEN] ; + } dout ; + + int channels ; +} STATE ; + + +static void usage_exit (void) ; +static void interleave_int (STATE * state) ; +static void interleave_double (STATE * state) ; + + +int +main (int argc, char **argv) +{ STATE state ; + SF_INFO sfinfo ; + int k, double_merge = 0 ; + + if (argc < 5) + { if (argc > 1) + puts ("\nError : need at least 2 input files.") ; + usage_exit () ; + } ; + + if (strcmp (argv [argc - 2], "-o") != 0) + { puts ("\nError : second last command line parameter should be '-o'.\n") ; + usage_exit () ; + } ; + + if (argc - 3 > MAX_INPUTS) + { printf ("\nError : Cannot handle more than %d input channels.\n\n", MAX_INPUTS) ; + exit (1) ; + } ; + + memset (&state, 0, sizeof (state)) ; + memset (&sfinfo, 0, sizeof (sfinfo)) ; + + for (k = 1 ; k < argc - 2 ; k++) + { + if ((state.infile [k - 1] = sf_open (argv [k], SFM_READ, &sfinfo)) == NULL) + { printf ("\nError : Not able to open input file '%s'\n%s\n", argv [k], sf_strerror (NULL)) ; + exit (1) ; + } ; + + if (sfinfo.channels != 1) + { printf ("\bError : Input file '%s' should be mono (has %d channels).\n", argv [k], sfinfo.channels) ; + exit (1) ; + } ; + + switch (sfinfo.format & SF_FORMAT_SUBMASK) + { case SF_FORMAT_FLOAT : + case SF_FORMAT_DOUBLE : + case SF_FORMAT_VORBIS : + double_merge = 1 ; + break ; + + default : + break ; + } ; + + state.channels ++ ; + } ; + + sfinfo.channels = state.channels ; + sfinfo.format = sfe_file_type_of_ext (argv [argc - 1], sfinfo.format) ; + + if ((state.outfile = sf_open (argv [argc - 1], SFM_WRITE, &sfinfo)) == NULL) + { printf ("Not able to open output file '%s'\n%s\n", argv [argc - 1], sf_strerror (NULL)) ; + exit (1) ; + } ; + + if (double_merge) + interleave_double (&state) ; + else + interleave_int (&state) ; + + for (k = 0 ; k < MAX_INPUTS ; k++) + if (state.infile [k] != NULL) + sf_close (state.infile [k]) ; + sf_close (state.outfile) ; + + return 0 ; +} /* main */ + +/*------------------------------------------------------------------------------ +*/ + + +static void +usage_exit (void) +{ puts ("\nUsage : sndfile-interleave ... -o \n") ; + puts ("Merge two or more mono files into a single multi-channel file.\n") ; + printf ("Using %s.\n\n", sf_version_string ()) ; + exit (0) ; +} /* usage_exit */ + + +static void +interleave_int (STATE * state) +{ int max_read_len, read_len ; + int ch, k ; + + do + { max_read_len = 0 ; + + for (ch = 0 ; ch < state->channels ; ch ++) + { read_len = sf_read_int (state->infile [ch], state->din.i, BUFFER_LEN) ; + if (read_len < BUFFER_LEN) + memset (state->din.i + read_len, 0, sizeof (state->din.i [0]) * (BUFFER_LEN - read_len)) ; + + for (k = 0 ; k < read_len ; k++) + state->dout.i [k * state->channels + ch] = state->din.i [k] ; + + max_read_len = MAX (max_read_len, read_len) ; + } ; + + sf_writef_int (state->outfile, state->dout.i, max_read_len) ; + } + while (max_read_len > 0) ; + +} /* interleave_int */ + + +static void +interleave_double (STATE * state) +{ int max_read_len, read_len ; + int ch, k ; + + do + { max_read_len = 0 ; + + for (ch = 0 ; ch < state->channels ; ch ++) + { read_len = sf_read_double (state->infile [ch], state->din.d, BUFFER_LEN) ; + if (read_len < BUFFER_LEN) + memset (state->din.d + read_len, 0, sizeof (state->din.d [0]) * (BUFFER_LEN - read_len)) ; + + for (k = 0 ; k < read_len ; k++) + state->dout.d [k * state->channels + ch] = state->din.d [k] ; + + max_read_len = MAX (max_read_len, read_len) ; + } ; + + sf_writef_double (state->outfile, state->dout.d, max_read_len) ; + } + while (max_read_len > 0) ; + +} /* interleave_double */