~ubuntu-branches/ubuntu/gutsy/audacity/gutsy-backports

« back to all changes in this revision

Viewing changes to lib-src/libsndfile/examples/sndfile-convert.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-18 21:58:19 UTC
  • mfrom: (13.1.2 hardy)
  • Revision ID: james.westby@ubuntu.com-20080218215819-tmbcf1rx238r8gdv
Tags: 1.3.4-1.1ubuntu1~gutsy1
Automated backport upload; no source changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
** Copyright (C) 1999-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
3
 
**
4
 
** This program is free software; you can redistribute it and/or modify
5
 
** it under the terms of the GNU General Public License as published by
6
 
** the Free Software Foundation; either version 2 of the License, or
7
 
** (at your option) any later version.
8
 
**
9
 
** This program is distributed in the hope that it will be useful,
10
 
** but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
** GNU General Public License for more details.
13
 
**
14
 
** You should have received a copy of the GNU General Public License
15
 
** along with this program; if not, write to the Free Software
16
 
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
 
*/
18
 
 
19
 
 
20
 
#include <stdio.h>
21
 
#include <stdlib.h>
22
 
#include <string.h>
23
 
#include <ctype.h>
24
 
 
25
 
#include <sndfile.h>
26
 
 
27
 
#define  BUFFER_LEN     1024
28
 
 
29
 
 
30
 
typedef struct
31
 
{       char    *infilename, *outfilename ;
32
 
        SF_INFO infileinfo, outfileinfo ;
33
 
} OptionData ;
34
 
 
35
 
typedef struct
36
 
{       const char      *ext ;
37
 
        int                     len ;
38
 
        int                     format ;
39
 
} OUTPUT_FORMAT_MAP ;
40
 
 
41
 
static void copy_metadata (SNDFILE *outfile, SNDFILE *infile) ;
42
 
static void copy_data_fp (SNDFILE *outfile, SNDFILE *infile, int channels) ;
43
 
static void copy_data_int (SNDFILE *outfile, SNDFILE *infile, int channels) ;
44
 
 
45
 
static OUTPUT_FORMAT_MAP format_map [] =
46
 
{
47
 
        {       "aif",          3,      SF_FORMAT_AIFF  },
48
 
        {       "wav",          0,      SF_FORMAT_WAV   },
49
 
        {       "au",           0,      SF_FORMAT_AU    },
50
 
        {       "caf",          0,      SF_FORMAT_CAF   },
51
 
        {       "flac",         0,      SF_FORMAT_FLAC  },
52
 
        {       "snd",          0,      SF_FORMAT_AU    },
53
 
        {       "svx",          0,      SF_FORMAT_SVX   },
54
 
        {       "paf",          0,      SF_ENDIAN_BIG | SF_FORMAT_PAF   },
55
 
        {       "fap",          0,      SF_ENDIAN_LITTLE | SF_FORMAT_PAF        },
56
 
        {       "gsm",          0,      SF_FORMAT_RAW   },
57
 
        {       "nist",         0,      SF_FORMAT_NIST  },
58
 
        {       "ircam",        0,      SF_FORMAT_IRCAM },
59
 
        {       "sf",           0,      SF_FORMAT_IRCAM },
60
 
        {       "voc",          0,      SF_FORMAT_VOC   },
61
 
        {       "w64",          0,      SF_FORMAT_W64   },
62
 
        {       "raw",          0,      SF_FORMAT_RAW   },
63
 
        {       "mat4",         0,      SF_FORMAT_MAT4  },
64
 
        {       "mat5",         0,      SF_FORMAT_MAT5  },
65
 
        {       "mat",          0,      SF_FORMAT_MAT4  },
66
 
        {       "pvf",          0,      SF_FORMAT_PVF   },
67
 
        {       "sds",          0,      SF_FORMAT_SDS   },
68
 
        {       "sd2",          0,      SF_FORMAT_SD2   },
69
 
        {       "vox",          0,      SF_FORMAT_RAW   },
70
 
        {       "xi",           0,      SF_FORMAT_XI    }
71
 
} ; /* format_map */
72
 
 
73
 
static int
74
 
guess_output_file_type (char *str, int format)
75
 
{       char    buffer [16], *cptr ;
76
 
        int             k ;
77
 
 
78
 
        format &= SF_FORMAT_SUBMASK ;
79
 
 
80
 
        if ((cptr = strrchr (str, '.')) == NULL)
81
 
                return 0 ;
82
 
 
83
 
        strncpy (buffer, cptr + 1, 15) ;
84
 
        buffer [15] = 0 ;
85
 
 
86
 
        for (k = 0 ; buffer [k] ; k++)
87
 
                buffer [k] = tolower ((buffer [k])) ;
88
 
 
89
 
        if (strcmp (buffer, "gsm") == 0)
90
 
                return SF_FORMAT_RAW | SF_FORMAT_GSM610 ;
91
 
 
92
 
        if (strcmp (buffer, "vox") == 0)
93
 
                return SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM ;
94
 
 
95
 
        for (k = 0 ; k < (int) (sizeof (format_map) / sizeof (format_map [0])) ; k++)
96
 
        {       if (format_map [k].len > 0 && strncmp (buffer, format_map [k].ext, format_map [k].len) == 0)
97
 
                        return format_map [k].format | format ;
98
 
                else if (strcmp (buffer, format_map [k].ext) == 0)
99
 
                        return format_map [k].format | format ;
100
 
                } ;
101
 
 
102
 
        return  0 ;
103
 
} /* guess_output_file_type */
104
 
 
105
 
 
106
 
static void
107
 
print_usage (char *progname)
108
 
{       SF_FORMAT_INFO  info ;
109
 
 
110
 
        int k ;
111
 
 
112
 
        printf ("\nUsage : %s [encoding] <input file> <output file>\n", progname) ;
113
 
        puts ("\n"
114
 
                "    where [encoding] may be one of the following:\n\n"
115
 
                "        -pcms8     : force the output to signed 8 bit pcm\n"
116
 
                "        -pcmu8     : force the output to unsigned 8 bit pcm\n"
117
 
                "        -pcm16     : force the output to 16 bit pcm\n"
118
 
                "        -pcm24     : force the output to 24 bit pcm\n"
119
 
                "        -pcm32     : force the output to 32 bit pcm\n"
120
 
                "        -float32   : force the output to 32 bit floating point"
121
 
                ) ;
122
 
        puts (
123
 
                "        -ulaw      : force the output ULAW\n"
124
 
                "        -alaw      : force the output ALAW\n"
125
 
                "        -ima-adpcm : force the output to IMA ADPCM (WAV only)\n"
126
 
                "        -ms-adpcm  : force the output to MS ADPCM (WAV only)\n"
127
 
                "        -gsm610    : force the GSM6.10 (WAV only)\n"
128
 
                "        -dwvw12    : force the output to 12 bit DWVW (AIFF only)\n"
129
 
                "        -dwvw16    : force the output to 16 bit DWVW (AIFF only)\n"
130
 
                "        -dwvw24    : force the output to 24 bit DWVW (AIFF only)\n"
131
 
                ) ;
132
 
 
133
 
        puts (
134
 
                "    The format of the output file is determined by the file extension of the\n"
135
 
                "    output file name. The following extensions are currently understood:\n"
136
 
                ) ;
137
 
 
138
 
        for (k = 0 ; k < (int) (sizeof (format_map) / sizeof (format_map [0])) ; k++)
139
 
        {       info.format = format_map [k].format ;
140
 
                sf_command (NULL, SFC_GET_FORMAT_INFO, &info, sizeof (info)) ;
141
 
                printf ("        %-10s : %s\n", format_map [k].ext, info.name) ;
142
 
                } ;
143
 
 
144
 
        puts ("") ;
145
 
} /* print_usage */
146
 
 
147
 
int
148
 
main (int argc, char * argv [])
149
 
{       char            *progname, *infilename, *outfilename ;
150
 
        SNDFILE         *infile = NULL, *outfile = NULL ;
151
 
        SF_INFO         sfinfo ;
152
 
        int                     k, outfilemajor, outfileminor = 0, infileminor ;
153
 
 
154
 
        progname = strrchr (argv [0], '/') ;
155
 
        progname = progname ? progname + 1 : argv [0] ;
156
 
 
157
 
        if (argc < 3 || argc > 5)
158
 
        {       print_usage (progname) ;
159
 
                return 1 ;
160
 
                } ;
161
 
 
162
 
        infilename = argv [argc-2] ;
163
 
        outfilename = argv [argc-1] ;
164
 
 
165
 
        if (strcmp (infilename, outfilename) == 0)
166
 
        {       printf ("Error : Input and output filenames are the same.\n\n") ;
167
 
                print_usage (progname) ;
168
 
                return 1 ;
169
 
                } ;
170
 
 
171
 
        if (infilename [0] == '-')
172
 
        {       printf ("Error : Input filename (%s) looks like an option.\n\n", infilename) ;
173
 
                print_usage (progname) ;
174
 
                return 1 ;
175
 
                } ;
176
 
 
177
 
        if (outfilename [0] == '-')
178
 
        {       printf ("Error : Output filename (%s) looks like an option.\n\n", outfilename) ;
179
 
                print_usage (progname) ;
180
 
                return 1 ;
181
 
                } ;
182
 
 
183
 
        for (k = 1 ; k < argc - 2 ; k++)
184
 
        {       if (! strcmp (argv [k], "-pcms8"))
185
 
                {       outfileminor = SF_FORMAT_PCM_S8 ;
186
 
                        continue ;
187
 
                        } ;
188
 
                if (! strcmp (argv [k], "-pcmu8"))
189
 
                {       outfileminor = SF_FORMAT_PCM_U8 ;
190
 
                        continue ;
191
 
                        } ;
192
 
                if (! strcmp (argv [k], "-pcm16"))
193
 
                {       outfileminor = SF_FORMAT_PCM_16 ;
194
 
                        continue ;
195
 
                        } ;
196
 
                if (! strcmp (argv [k], "-pcm24"))
197
 
                {       outfileminor = SF_FORMAT_PCM_24 ;
198
 
                        continue ;
199
 
                        } ;
200
 
                if (! strcmp (argv [k], "-pcm32"))
201
 
                {       outfileminor = SF_FORMAT_PCM_32 ;
202
 
                        continue ;
203
 
                        } ;
204
 
                if (! strcmp (argv [k], "-float32"))
205
 
                {       outfileminor = SF_FORMAT_FLOAT ;
206
 
                        continue ;
207
 
                        } ;
208
 
                if (! strcmp (argv [k], "-ulaw"))
209
 
                {       outfileminor = SF_FORMAT_ULAW ;
210
 
                        continue ;
211
 
                        } ;
212
 
                if (! strcmp (argv [k], "-alaw"))
213
 
                {       outfileminor = SF_FORMAT_ALAW ;
214
 
                        continue ;
215
 
                        } ;
216
 
                if (! strcmp (argv [k], "-ima-adpcm"))
217
 
                {       outfileminor = SF_FORMAT_IMA_ADPCM ;
218
 
                        continue ;
219
 
                        } ;
220
 
                if (! strcmp (argv [k], "-ms-adpcm"))
221
 
                {       outfileminor = SF_FORMAT_MS_ADPCM ;
222
 
                        continue ;
223
 
                        } ;
224
 
                if (! strcmp (argv [k], "-gsm610"))
225
 
                {       outfileminor = SF_FORMAT_GSM610 ;
226
 
                        continue ;
227
 
                        } ;
228
 
                if (! strcmp (argv [k], "-dwvw12"))
229
 
                {       outfileminor = SF_FORMAT_DWVW_12 ;
230
 
                        continue ;
231
 
                        } ;
232
 
                if (! strcmp (argv [k], "-dwvw16"))
233
 
                {       outfileminor = SF_FORMAT_DWVW_16 ;
234
 
                        continue ;
235
 
                        } ;
236
 
                if (! strcmp (argv [k], "-dwvw24"))
237
 
                {       outfileminor = SF_FORMAT_DWVW_24 ;
238
 
                        continue ;
239
 
                        } ;
240
 
 
241
 
                printf ("Error : Not able to decode argunment '%s'.\n", argv [k]) ;
242
 
                exit (1) ;
243
 
                } ;
244
 
 
245
 
        if ((infile = sf_open (infilename, SFM_READ, &sfinfo)) == NULL)
246
 
        {       printf ("Not able to open input file %s.\n", infilename) ;
247
 
                puts (sf_strerror (NULL)) ;
248
 
                return 1 ;
249
 
                } ;
250
 
 
251
 
        infileminor = sfinfo.format & SF_FORMAT_SUBMASK ;
252
 
 
253
 
        if ((sfinfo.format = guess_output_file_type (outfilename, sfinfo.format)) == 0)
254
 
        {       printf ("Error : Not able to determine output file type for %s.\n", outfilename) ;
255
 
                return 1 ;
256
 
                } ;
257
 
 
258
 
        outfilemajor = sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_ENDMASK) ;
259
 
 
260
 
        if (outfileminor == 0)
261
 
                outfileminor = sfinfo.format & SF_FORMAT_SUBMASK ;
262
 
 
263
 
        if (outfileminor != 0)
264
 
                sfinfo.format = outfilemajor | outfileminor ;
265
 
        else
266
 
                sfinfo.format = outfilemajor | (sfinfo.format & SF_FORMAT_SUBMASK) ;
267
 
 
268
 
        if ((sfinfo.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_XI)
269
 
                switch (sfinfo.format & SF_FORMAT_SUBMASK)
270
 
                {       case SF_FORMAT_PCM_16 :
271
 
                                        sfinfo.format = outfilemajor | SF_FORMAT_DPCM_16 ;
272
 
                                        break ;
273
 
 
274
 
                        case SF_FORMAT_PCM_S8 :
275
 
                        case SF_FORMAT_PCM_U8 :
276
 
                                        sfinfo.format = outfilemajor | SF_FORMAT_DPCM_8 ;
277
 
                                        break ;
278
 
                        } ;
279
 
 
280
 
        if (sf_format_check (&sfinfo) == 0)
281
 
        {       printf ("Error : output file format is invalid (0x%08X).\n", sfinfo.format) ;
282
 
                return 1 ;
283
 
                } ;
284
 
 
285
 
        /* Open the output file. */
286
 
        if ((outfile = sf_open (outfilename, SFM_WRITE, &sfinfo)) == NULL)
287
 
        {       printf ("Not able to open output file %s : %s\n", outfilename, sf_strerror (NULL)) ;
288
 
                return 1 ;
289
 
                } ;
290
 
 
291
 
        /* Copy the metadata */
292
 
        copy_metadata (outfile, infile) ;
293
 
 
294
 
        if ((outfileminor == SF_FORMAT_DOUBLE) || (outfileminor == SF_FORMAT_FLOAT) ||
295
 
                                (infileminor == SF_FORMAT_DOUBLE) || (infileminor == SF_FORMAT_FLOAT))
296
 
                copy_data_fp (outfile, infile, sfinfo.channels) ;
297
 
        else
298
 
                copy_data_int (outfile, infile, sfinfo.channels) ;
299
 
 
300
 
        sf_close (infile) ;
301
 
        sf_close (outfile) ;
302
 
 
303
 
        return 0 ;
304
 
} /* main */
305
 
 
306
 
static void
307
 
copy_metadata (SNDFILE *outfile, SNDFILE *infile)
308
 
{       const char *str ;
309
 
        int k, err = 0 ;
310
 
 
311
 
        for (k = SF_STR_FIRST ; k <= SF_STR_LAST ; k++)
312
 
        {       str = sf_get_string (infile, k) ;
313
 
                if (str != NULL)
314
 
                        err = sf_set_string (outfile, k, str) ;
315
 
                } ;
316
 
 
317
 
} /* copy_metadata */
318
 
 
319
 
static void
320
 
copy_data_fp (SNDFILE *outfile, SNDFILE *infile, int channels)
321
 
{       static double   data [BUFFER_LEN], max ;
322
 
        int             frames, readcount, k ;
323
 
 
324
 
        frames = BUFFER_LEN / channels ;
325
 
        readcount = frames ;
326
 
 
327
 
        sf_command (infile, SFC_CALC_SIGNAL_MAX, &max, sizeof (max)) ;
328
 
 
329
 
        if (max < 1.0)
330
 
        {       while (readcount > 0)
331
 
                {       readcount = sf_readf_double (infile, data, frames) ;
332
 
                        sf_writef_double (outfile, data, readcount) ;
333
 
                        } ;
334
 
                }
335
 
        else
336
 
        {       sf_command (infile, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
337
 
 
338
 
                while (readcount > 0)
339
 
                {       readcount = sf_readf_double (infile, data, frames) ;
340
 
                        for (k = 0 ; k < readcount * channels ; k++)
341
 
                                data [k] /= max ;
342
 
                        sf_writef_double (outfile, data, readcount) ;
343
 
                        } ;
344
 
                } ;
345
 
 
346
 
        return ;
347
 
} /* copy_data_fp */
348
 
 
349
 
static void
350
 
copy_data_int (SNDFILE *outfile, SNDFILE *infile, int channels)
351
 
{       static int      data [BUFFER_LEN] ;
352
 
        int             frames, readcount ;
353
 
 
354
 
        frames = BUFFER_LEN / channels ;
355
 
        readcount = frames ;
356
 
 
357
 
        while (readcount > 0)
358
 
        {       readcount = sf_readf_int (infile, data, frames) ;
359
 
                sf_writef_int (outfile, data, readcount) ;
360
 
                } ;
361
 
 
362
 
        return ;
363
 
} /* copy_data_int */
364
 
 
365
 
/*
366
 
** Do not edit or modify anything in this comment block.
367
 
** The arch-tag line is a file identity tag for the GNU Arch
368
 
** revision control system.
369
 
**
370
 
** arch-tag: 259682b3-2887-48a6-b5bb-3cde00521ba3
371
 
*/