df80b042220e1fcc0f3ff8af654d09d79c627bfd
2 ** Copyright (C) 2009-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
4 ** All rights reserved.
6 ** Redistribution and use in source and binary forms, with or without
7 ** modification, are permitted provided that the following conditions are
10 ** * Redistributions of source code must retain the above copyright
11 ** notice, this list of conditions and the following disclaimer.
12 ** * Redistributions in binary form must reproduce the above copyright
13 ** notice, this list of conditions and the following disclaimer in
14 ** the documentation and/or other materials provided with the
16 ** * Neither the author nor the names of any contributors may be used
17 ** to endorse or promote products derived from this software without
18 ** specific prior written permission.
20 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 ** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 ** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
30 ** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 #define BUFFER_LEN 4096
41 #define MAX_CHANNELS 16
46 SNDFILE
* outfile
[MAX_CHANNELS
] ;
49 { double d
[MAX_CHANNELS
* BUFFER_LEN
] ;
50 int i
[MAX_CHANNELS
* BUFFER_LEN
] ;
54 { double d
[BUFFER_LEN
] ;
61 static void usage_exit (void) ;
63 static void deinterleave_int (STATE
* state
) ;
64 static void deinterleave_double (STATE
* state
) ;
67 main (int argc
, char **argv
)
70 char pathname
[512], ext
[32], *cptr
;
71 int ch
, double_split
;
75 puts ("\nError : need a single input file.\n") ;
79 memset (&state
, 0, sizeof (state
)) ;
80 memset (&sfinfo
, 0, sizeof (sfinfo
)) ;
82 if ((state
.infile
= sf_open (argv
[1], SFM_READ
, &sfinfo
)) == NULL
)
83 { printf ("\nError : Not able to open input file '%s'\n%s\n", argv
[1], sf_strerror (NULL
)) ;
87 if (sfinfo
.channels
< 2)
88 { printf ("\nError : Input file '%s' only has one channel.\n", argv
[1]) ;
92 state
.channels
= sfinfo
.channels
;
95 snprintf (pathname
, sizeof (pathname
), "%s", argv
[1]) ;
96 if ((cptr
= strrchr (pathname
, '.')) == NULL
)
99 { snprintf (ext
, sizeof (ext
), "%s", cptr
) ;
103 printf ("Input file : %s\n", pathname
) ;
104 puts ("Output files :") ;
106 for (ch
= 0 ; ch
< state
.channels
; ch
++)
107 { char filename
[520] ;
109 snprintf (filename
, sizeof (filename
), "%s_%02d%s", pathname
, ch
, ext
) ;
111 if ((state
.outfile
[ch
] = sf_open (filename
, SFM_WRITE
, &sfinfo
)) == NULL
)
112 { printf ("Not able to open output file '%s'\n%s\n", filename
, sf_strerror (NULL
)) ;
116 printf (" %s\n", filename
) ;
119 switch (sfinfo
.format
& SF_FORMAT_SUBMASK
)
120 { case SF_FORMAT_FLOAT
:
121 case SF_FORMAT_DOUBLE
:
122 case SF_FORMAT_VORBIS
:
132 deinterleave_double (&state
) ;
134 deinterleave_int (&state
) ;
136 sf_close (state
.infile
) ;
137 for (ch
= 0 ; ch
< MAX_CHANNELS
; ch
++)
138 if (state
.outfile
[ch
] != NULL
)
139 sf_close (state
.outfile
[ch
]) ;
144 /*------------------------------------------------------------------------------
149 { puts ("\nUsage : sndfile-deinterleave <filename>\n") ;
151 "Split a mutli-channel file into a set of mono files.\n"
153 "If the input file is named 'a.wav', the output files will be named\n"
154 "a_00.wav, a_01.wav and so on.\n"
156 printf ("Using %s.\n\n", sf_version_string ()) ;
161 deinterleave_int (STATE
* state
)
166 { read_len
= sf_readf_int (state
->infile
, state
->din
.i
, BUFFER_LEN
) ;
168 for (ch
= 0 ; ch
< state
->channels
; ch
++)
169 { for (k
= 0 ; k
< read_len
; k
++)
170 state
->dout
.i
[k
] = state
->din
.i
[k
* state
->channels
+ ch
] ;
171 sf_write_int (state
->outfile
[ch
], state
->dout
.i
, read_len
) ;
174 while (read_len
> 0) ;
176 } /* deinterleave_int */
179 deinterleave_double (STATE
* state
)
184 { read_len
= sf_readf_double (state
->infile
, state
->din
.d
, BUFFER_LEN
) ;
186 for (ch
= 0 ; ch
< state
->channels
; ch
++)
187 { for (k
= 0 ; k
< read_len
; k
++)
188 state
->dout
.d
[k
] = state
->din
.d
[k
* state
->channels
+ ch
] ;
189 sf_write_double (state
->outfile
[ch
], state
->dout
.d
, read_len
) ;
192 while (read_len
> 0) ;
194 } /* deinterleave_double */