annotate src/libsndfile-1.0.25/programs/sndfile-interleave.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents c7265573341e
children
rev   line source
Chris@0 1 /*
Chris@0 2 ** Copyright (C) 2009-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
Chris@0 3 **
Chris@0 4 ** All rights reserved.
Chris@0 5 **
Chris@0 6 ** Redistribution and use in source and binary forms, with or without
Chris@0 7 ** modification, are permitted provided that the following conditions are
Chris@0 8 ** met:
Chris@0 9 **
Chris@0 10 ** * Redistributions of source code must retain the above copyright
Chris@0 11 ** notice, this list of conditions and the following disclaimer.
Chris@0 12 ** * Redistributions in binary form must reproduce the above copyright
Chris@0 13 ** notice, this list of conditions and the following disclaimer in
Chris@0 14 ** the documentation and/or other materials provided with the
Chris@0 15 ** distribution.
Chris@0 16 ** * Neither the author nor the names of any contributors may be used
Chris@0 17 ** to endorse or promote products derived from this software without
Chris@0 18 ** specific prior written permission.
Chris@0 19 **
Chris@0 20 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Chris@0 21 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
Chris@0 22 ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
Chris@0 23 ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
Chris@0 24 ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Chris@0 25 ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
Chris@0 26 ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
Chris@0 27 ** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
Chris@0 28 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
Chris@0 29 ** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
Chris@0 30 ** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Chris@0 31 */
Chris@0 32
Chris@0 33 #include <stdio.h>
Chris@0 34 #include <stdlib.h>
Chris@0 35 #include <string.h>
Chris@0 36 #include <sndfile.h>
Chris@0 37
Chris@0 38 #include "common.h"
Chris@0 39
Chris@0 40 #define BUFFER_LEN 4096
Chris@0 41 #define MAX_INPUTS 16
Chris@0 42
Chris@0 43
Chris@0 44 typedef struct
Chris@0 45 { SNDFILE * infile [MAX_INPUTS] ;
Chris@0 46 SNDFILE * outfile ;
Chris@0 47
Chris@0 48 union
Chris@0 49 { double d [BUFFER_LEN] ;
Chris@0 50 int i [BUFFER_LEN] ;
Chris@0 51 } din ;
Chris@0 52
Chris@0 53 union
Chris@0 54
Chris@0 55 { double d [MAX_INPUTS * BUFFER_LEN] ;
Chris@0 56 int i [MAX_INPUTS * BUFFER_LEN] ;
Chris@0 57 } dout ;
Chris@0 58
Chris@0 59 int channels ;
Chris@0 60 } STATE ;
Chris@0 61
Chris@0 62
Chris@0 63 static void usage_exit (void) ;
Chris@0 64 static void interleave_int (STATE * state) ;
Chris@0 65 static void interleave_double (STATE * state) ;
Chris@0 66
Chris@0 67
Chris@0 68 int
Chris@0 69 main (int argc, char **argv)
Chris@0 70 { STATE state ;
Chris@0 71 SF_INFO sfinfo ;
Chris@0 72 int k, double_merge = 0 ;
Chris@0 73
Chris@0 74 if (argc < 5)
Chris@0 75 { if (argc > 1)
Chris@0 76 puts ("\nError : need at least 2 input files.") ;
Chris@0 77 usage_exit () ;
Chris@0 78 } ;
Chris@0 79
Chris@0 80 if (strcmp (argv [argc - 2], "-o") != 0)
Chris@0 81 { puts ("\nError : second last command line parameter should be '-o'.\n") ;
Chris@0 82 usage_exit () ;
Chris@0 83 } ;
Chris@0 84
Chris@0 85 if (argc - 3 > MAX_INPUTS)
Chris@0 86 { printf ("\nError : Cannot handle more than %d input channels.\n\n", MAX_INPUTS) ;
Chris@0 87 exit (1) ;
Chris@0 88 } ;
Chris@0 89
Chris@0 90 memset (&state, 0, sizeof (state)) ;
Chris@0 91 memset (&sfinfo, 0, sizeof (sfinfo)) ;
Chris@0 92
Chris@0 93 for (k = 1 ; k < argc - 2 ; k++)
Chris@0 94 {
Chris@0 95 if ((state.infile [k - 1] = sf_open (argv [k], SFM_READ, &sfinfo)) == NULL)
Chris@0 96 { printf ("\nError : Not able to open input file '%s'\n%s\n", argv [k], sf_strerror (NULL)) ;
Chris@0 97 exit (1) ;
Chris@0 98 } ;
Chris@0 99
Chris@0 100 if (sfinfo.channels != 1)
Chris@0 101 { printf ("\bError : Input file '%s' should be mono (has %d channels).\n", argv [k], sfinfo.channels) ;
Chris@0 102 exit (1) ;
Chris@0 103 } ;
Chris@0 104
Chris@0 105 switch (sfinfo.format & SF_FORMAT_SUBMASK)
Chris@0 106 { case SF_FORMAT_FLOAT :
Chris@0 107 case SF_FORMAT_DOUBLE :
Chris@0 108 case SF_FORMAT_VORBIS :
Chris@0 109 double_merge = 1 ;
Chris@0 110 break ;
Chris@0 111
Chris@0 112 default :
Chris@0 113 break ;
Chris@0 114 } ;
Chris@0 115
Chris@0 116 state.channels ++ ;
Chris@0 117 } ;
Chris@0 118
Chris@0 119 sfinfo.channels = state.channels ;
Chris@0 120 sfinfo.format = sfe_file_type_of_ext (argv [argc - 1], sfinfo.format) ;
Chris@0 121
Chris@0 122 if ((state.outfile = sf_open (argv [argc - 1], SFM_WRITE, &sfinfo)) == NULL)
Chris@0 123 { printf ("Not able to open output file '%s'\n%s\n", argv [argc - 1], sf_strerror (NULL)) ;
Chris@0 124 exit (1) ;
Chris@0 125 } ;
Chris@0 126
Chris@0 127 if (double_merge)
Chris@0 128 interleave_double (&state) ;
Chris@0 129 else
Chris@0 130 interleave_int (&state) ;
Chris@0 131
Chris@0 132 for (k = 0 ; k < MAX_INPUTS ; k++)
Chris@0 133 if (state.infile [k] != NULL)
Chris@0 134 sf_close (state.infile [k]) ;
Chris@0 135 sf_close (state.outfile) ;
Chris@0 136
Chris@0 137 return 0 ;
Chris@0 138 } /* main */
Chris@0 139
Chris@0 140 /*------------------------------------------------------------------------------
Chris@0 141 */
Chris@0 142
Chris@0 143
Chris@0 144 static void
Chris@0 145 usage_exit (void)
Chris@0 146 { puts ("\nUsage : sndfile-interleave <input 1> <input 2> ... -o <output file>\n") ;
Chris@0 147 puts ("Merge two or more mono files into a single multi-channel file.\n") ;
Chris@0 148 printf ("Using %s.\n\n", sf_version_string ()) ;
Chris@0 149 exit (0) ;
Chris@0 150 } /* usage_exit */
Chris@0 151
Chris@0 152
Chris@0 153 static void
Chris@0 154 interleave_int (STATE * state)
Chris@0 155 { int max_read_len, read_len ;
Chris@0 156 int ch, k ;
Chris@0 157
Chris@0 158 do
Chris@0 159 { max_read_len = 0 ;
Chris@0 160
Chris@0 161 for (ch = 0 ; ch < state->channels ; ch ++)
Chris@0 162 { read_len = sf_read_int (state->infile [ch], state->din.i, BUFFER_LEN) ;
Chris@0 163 if (read_len < BUFFER_LEN)
Chris@0 164 memset (state->din.i + read_len, 0, sizeof (state->din.i [0]) * (BUFFER_LEN - read_len)) ;
Chris@0 165
Chris@0 166 for (k = 0 ; k < read_len ; k++)
Chris@0 167 state->dout.i [k * state->channels + ch] = state->din.i [k] ;
Chris@0 168
Chris@0 169 max_read_len = MAX (max_read_len, read_len) ;
Chris@0 170 } ;
Chris@0 171
Chris@0 172 sf_writef_int (state->outfile, state->dout.i, max_read_len) ;
Chris@0 173 }
Chris@0 174 while (max_read_len > 0) ;
Chris@0 175
Chris@0 176 } /* interleave_int */
Chris@0 177
Chris@0 178
Chris@0 179 static void
Chris@0 180 interleave_double (STATE * state)
Chris@0 181 { int max_read_len, read_len ;
Chris@0 182 int ch, k ;
Chris@0 183
Chris@0 184 do
Chris@0 185 { max_read_len = 0 ;
Chris@0 186
Chris@0 187 for (ch = 0 ; ch < state->channels ; ch ++)
Chris@0 188 { read_len = sf_read_double (state->infile [ch], state->din.d, BUFFER_LEN) ;
Chris@0 189 if (read_len < BUFFER_LEN)
Chris@0 190 memset (state->din.d + read_len, 0, sizeof (state->din.d [0]) * (BUFFER_LEN - read_len)) ;
Chris@0 191
Chris@0 192 for (k = 0 ; k < read_len ; k++)
Chris@0 193 state->dout.d [k * state->channels + ch] = state->din.d [k] ;
Chris@0 194
Chris@0 195 max_read_len = MAX (max_read_len, read_len) ;
Chris@0 196 } ;
Chris@0 197
Chris@0 198 sf_writef_double (state->outfile, state->dout.d, max_read_len) ;
Chris@0 199 }
Chris@0 200 while (max_read_len > 0) ;
Chris@0 201
Chris@0 202 } /* interleave_double */