2 ** Copyright (C) 1999-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.
44 { char *infilename
, *outfilename
;
45 SF_INFO infileinfo
, outfileinfo
;
48 static void copy_metadata (SNDFILE
*outfile
, SNDFILE
*infile
, int channels
) ;
51 usage_exit (const char *progname
)
53 printf ("\nUsage : %s [options] [encoding] <input file> <output file>\n", progname
) ;
55 " where [option] may be:\n\n"
56 " -override-sample-rate=X : force sample rate of input to X\n"
60 " where [encoding] may be one of the following:\n\n"
61 " -pcms8 : force the output to signed 8 bit pcm\n"
62 " -pcmu8 : force the output to unsigned 8 bit pcm\n"
63 " -pcm16 : force the output to 16 bit pcm\n"
64 " -pcm24 : force the output to 24 bit pcm\n"
65 " -pcm32 : force the output to 32 bit pcm\n"
66 " -float32 : force the output to 32 bit floating point"
69 " -ulaw : force the output ULAW\n"
70 " -alaw : force the output ALAW\n"
71 " -ima-adpcm : force the output to IMA ADPCM (WAV only)\n"
72 " -ms-adpcm : force the output to MS ADPCM (WAV only)\n"
73 " -gsm610 : force the GSM6.10 (WAV only)\n"
74 " -dwvw12 : force the output to 12 bit DWVW (AIFF only)\n"
75 " -dwvw16 : force the output to 16 bit DWVW (AIFF only)\n"
76 " -dwvw24 : force the output to 24 bit DWVW (AIFF only)\n"
77 " -vorbis : force the output to Vorbis (OGG only)\n"
81 " The format of the output file is determined by the file extension of the\n"
82 " output file name. The following extensions are currently understood:\n"
85 sfe_dump_format_map () ;
92 main (int argc
, char * argv
[])
93 { const char *progname
, *infilename
, *outfilename
;
94 SNDFILE
*infile
= NULL
, *outfile
= NULL
;
96 int k
, outfilemajor
, outfileminor
= 0, infileminor
;
97 int override_sample_rate
= 0 ; /* assume no sample rate override. */
99 progname
= program_name (argv
[0]) ;
101 if (argc
< 3 || argc
> 5)
102 { usage_exit (progname
) ;
106 infilename
= argv
[argc
-2] ;
107 outfilename
= argv
[argc
-1] ;
109 if (strcmp (infilename
, outfilename
) == 0)
110 { printf ("Error : Input and output filenames are the same.\n\n") ;
111 usage_exit (progname
) ;
115 if (strlen (infilename
) > 1 && infilename
[0] == '-')
116 { printf ("Error : Input filename (%s) looks like an option.\n\n", infilename
) ;
117 usage_exit (progname
) ;
121 if (outfilename
[0] == '-')
122 { printf ("Error : Output filename (%s) looks like an option.\n\n", outfilename
) ;
123 usage_exit (progname
) ;
127 for (k
= 1 ; k
< argc
- 2 ; k
++)
128 { if (! strcmp (argv
[k
], "-pcms8"))
129 { outfileminor
= SF_FORMAT_PCM_S8
;
132 if (! strcmp (argv
[k
], "-pcmu8"))
133 { outfileminor
= SF_FORMAT_PCM_U8
;
136 if (! strcmp (argv
[k
], "-pcm16"))
137 { outfileminor
= SF_FORMAT_PCM_16
;
140 if (! strcmp (argv
[k
], "-pcm24"))
141 { outfileminor
= SF_FORMAT_PCM_24
;
144 if (! strcmp (argv
[k
], "-pcm32"))
145 { outfileminor
= SF_FORMAT_PCM_32
;
148 if (! strcmp (argv
[k
], "-float32"))
149 { outfileminor
= SF_FORMAT_FLOAT
;
152 if (! strcmp (argv
[k
], "-ulaw"))
153 { outfileminor
= SF_FORMAT_ULAW
;
156 if (! strcmp (argv
[k
], "-alaw"))
157 { outfileminor
= SF_FORMAT_ALAW
;
160 if (! strcmp (argv
[k
], "-ima-adpcm"))
161 { outfileminor
= SF_FORMAT_IMA_ADPCM
;
164 if (! strcmp (argv
[k
], "-ms-adpcm"))
165 { outfileminor
= SF_FORMAT_MS_ADPCM
;
168 if (! strcmp (argv
[k
], "-gsm610"))
169 { outfileminor
= SF_FORMAT_GSM610
;
172 if (! strcmp (argv
[k
], "-dwvw12"))
173 { outfileminor
= SF_FORMAT_DWVW_12
;
176 if (! strcmp (argv
[k
], "-dwvw16"))
177 { outfileminor
= SF_FORMAT_DWVW_16
;
180 if (! strcmp (argv
[k
], "-dwvw24"))
181 { outfileminor
= SF_FORMAT_DWVW_24
;
184 if (! strcmp (argv
[k
], "-vorbis"))
185 { outfileminor
= SF_FORMAT_VORBIS
;
189 if (strstr (argv
[k
], "-override-sample-rate=") == argv
[k
])
192 ptr
= argv
[k
] + strlen ("-override-sample-rate=") ;
193 override_sample_rate
= atoi (ptr
) ;
197 printf ("Error : Not able to decode argunment '%s'.\n", argv
[k
]) ;
201 memset (&sfinfo
, 0, sizeof (sfinfo
)) ;
203 if ((infile
= sf_open (infilename
, SFM_READ
, &sfinfo
)) == NULL
)
204 { printf ("Not able to open input file %s.\n", infilename
) ;
205 puts (sf_strerror (NULL
)) ;
209 /* Update sample rate if forced to something else. */
210 if (override_sample_rate
)
211 sfinfo
.samplerate
= override_sample_rate
;
213 infileminor
= sfinfo
.format
& SF_FORMAT_SUBMASK
;
215 if ((sfinfo
.format
= sfe_file_type_of_ext (outfilename
, sfinfo
.format
)) == 0)
216 { printf ("Error : Not able to determine output file type for %s.\n", outfilename
) ;
220 outfilemajor
= sfinfo
.format
& (SF_FORMAT_TYPEMASK
| SF_FORMAT_ENDMASK
) ;
222 if (outfileminor
== 0)
223 outfileminor
= sfinfo
.format
& SF_FORMAT_SUBMASK
;
225 if (outfileminor
!= 0)
226 sfinfo
.format
= outfilemajor
| outfileminor
;
228 sfinfo
.format
= outfilemajor
| (sfinfo
.format
& SF_FORMAT_SUBMASK
) ;
230 if ((sfinfo
.format
& SF_FORMAT_TYPEMASK
) == SF_FORMAT_XI
)
231 switch (sfinfo
.format
& SF_FORMAT_SUBMASK
)
232 { case SF_FORMAT_PCM_16
:
233 sfinfo
.format
= outfilemajor
| SF_FORMAT_DPCM_16
;
236 case SF_FORMAT_PCM_S8
:
237 case SF_FORMAT_PCM_U8
:
238 sfinfo
.format
= outfilemajor
| SF_FORMAT_DPCM_8
;
242 if (sf_format_check (&sfinfo
) == 0)
243 { printf ("Error : output file format is invalid (0x%08X).\n", sfinfo
.format
) ;
247 /* Open the output file. */
248 if ((outfile
= sf_open (outfilename
, SFM_WRITE
, &sfinfo
)) == NULL
)
249 { printf ("Not able to open output file %s : %s\n", outfilename
, sf_strerror (NULL
)) ;
253 /* Copy the metadata */
254 copy_metadata (outfile
, infile
, sfinfo
.channels
) ;
256 if ((outfileminor
== SF_FORMAT_DOUBLE
) || (outfileminor
== SF_FORMAT_FLOAT
)
257 || (infileminor
== SF_FORMAT_DOUBLE
) || (infileminor
== SF_FORMAT_FLOAT
)
258 || (infileminor
== SF_FORMAT_VORBIS
) || (outfileminor
== SF_FORMAT_VORBIS
))
259 sfe_copy_data_fp (outfile
, infile
, sfinfo
.channels
) ;
261 sfe_copy_data_int (outfile
, infile
, sfinfo
.channels
) ;
270 copy_metadata (SNDFILE
*outfile
, SNDFILE
*infile
, int channels
)
271 { SF_INSTRUMENT inst
;
272 SF_BROADCAST_INFO_2K binfo
;
274 int k
, chanmap
[256] ;
276 for (k
= SF_STR_FIRST
; k
<= SF_STR_LAST
; k
++)
277 { str
= sf_get_string (infile
, k
) ;
279 sf_set_string (outfile
, k
, str
) ;
282 memset (&inst
, 0, sizeof (inst
)) ;
283 memset (&binfo
, 0, sizeof (binfo
)) ;
285 if (channels
< ARRAY_LEN (chanmap
))
286 { size_t size
= channels
* sizeof (chanmap
[0]) ;
288 if (sf_command (infile
, SFC_GET_CHANNEL_MAP_INFO
, chanmap
, size
) == SF_TRUE
)
289 sf_command (outfile
, SFC_SET_CHANNEL_MAP_INFO
, chanmap
, size
) ;
292 if (sf_command (infile
, SFC_GET_INSTRUMENT
, &inst
, sizeof (inst
)) == SF_TRUE
)
293 sf_command (outfile
, SFC_SET_INSTRUMENT
, &inst
, sizeof (inst
)) ;
295 if (sf_command (infile
, SFC_GET_BROADCAST_INFO
, &binfo
, sizeof (binfo
)) == SF_TRUE
)
296 sf_command (outfile
, SFC_SET_BROADCAST_INFO
, &binfo
, sizeof (binfo
)) ;
298 } /* copy_metadata */