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

« back to all changes in this revision

Viewing changes to lib-src/libsndfile/examples/sndfile-info.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-2006 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
 
#include        <stdio.h>
20
 
#include        <stdlib.h>
21
 
#include        <string.h>
22
 
#include        <ctype.h>
23
 
#include        <math.h>
24
 
 
25
 
#include        <sndfile.h>
26
 
 
27
 
#define BUFFER_LEN              (1 << 16)
28
 
 
29
 
#if (defined (WIN32) || defined (_WIN32))
30
 
#define snprintf        _snprintf
31
 
#endif
32
 
 
33
 
static void print_version (void) ;
34
 
static void print_usage (const char *progname) ;
35
 
 
36
 
static void info_dump (const char *filename) ;
37
 
static void instrument_dump (const char *filename) ;
38
 
static void broadcast_dump (const char *filename) ;
39
 
 
40
 
int
41
 
main (int argc, char *argv [])
42
 
{       int     k ;
43
 
 
44
 
        print_version () ;
45
 
 
46
 
        if (argc < 2 || strcmp (argv [1], "--help") == 0 || strcmp (argv [1], "-h") == 0)
47
 
        {       char *progname ;
48
 
 
49
 
                progname = strrchr (argv [0], '/') ;
50
 
                progname = progname ? progname + 1 : argv [0] ;
51
 
 
52
 
                print_usage (progname) ;
53
 
                return 1 ;
54
 
                } ;
55
 
 
56
 
        if (strcmp (argv [1], "-i") == 0)
57
 
        {       instrument_dump (argv [2]) ;
58
 
                return 0 ;
59
 
                } ;
60
 
 
61
 
        if (strcmp (argv [1], "-b") == 0)
62
 
        {       broadcast_dump (argv [2]) ;
63
 
                return 0 ;
64
 
                } ;
65
 
 
66
 
        for (k = 1 ; k < argc ; k++)
67
 
                info_dump (argv [k]) ;
68
 
 
69
 
        return 0 ;
70
 
} /* main */
71
 
 
72
 
/*==============================================================================
73
 
**      Print version and usage.
74
 
*/
75
 
 
76
 
static double   data [BUFFER_LEN] ;
77
 
 
78
 
static void
79
 
print_version (void)
80
 
{       char buffer [256] ;
81
 
 
82
 
        sf_command (NULL, SFC_GET_LIB_VERSION, buffer, sizeof (buffer)) ;
83
 
        printf ("\nVersion : %s\n\n", buffer) ;
84
 
} /* print_version */
85
 
 
86
 
 
87
 
static void
88
 
print_usage (const char *progname)
89
 
{       printf ("Usage :\n  %s <file> ...\n", progname) ;
90
 
        printf ("    Prints out information about one or more sound files.\n\n") ;
91
 
        printf ("  %s -i <file>\n", progname) ;
92
 
        printf ("    Prints out the instrument data for the given file.\n\n") ;
93
 
        printf ("  %s -b <file>\n", progname) ;
94
 
        printf ("    Prints out the broadcast WAV info for the given file.\n\n") ;
95
 
#if (defined (_WIN32) || defined (WIN32))
96
 
                printf ("This is a Unix style command line application which\n"
97
 
                                "should be run in a MSDOS box or Command Shell window.\n\n") ;
98
 
                printf ("Sleeping for 5 seconds before exiting.\n\n") ;
99
 
                fflush (stdout) ;
100
 
 
101
 
                /* This is the officially blessed by microsoft way but I can't get
102
 
                ** it to link.
103
 
                **     Sleep (15) ;
104
 
                ** Instead, use this:
105
 
                */
106
 
                _sleep (5 * 1000) ;
107
 
#endif
108
 
} /* print_usage */
109
 
 
110
 
/*==============================================================================
111
 
**      Dumping of sndfile info.
112
 
*/
113
 
 
114
 
static double   data [BUFFER_LEN] ;
115
 
 
116
 
static double
117
 
get_signal_max (SNDFILE *file)
118
 
{       double  max, temp ;
119
 
        int             readcount, k, save_state ;
120
 
 
121
 
        save_state = sf_command (file, SFC_GET_NORM_DOUBLE, NULL, 0) ;
122
 
        sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
123
 
 
124
 
        max = 0.0 ;
125
 
        while ((readcount = sf_read_double (file, data, BUFFER_LEN)))
126
 
        {       for (k = 0 ; k < readcount ; k++)
127
 
                {       temp = fabs (data [k]) ;
128
 
                        if (temp > max)
129
 
                                max = temp ;
130
 
                        } ;
131
 
                } ;
132
 
 
133
 
        sf_command (file, SFC_SET_NORM_DOUBLE, NULL, save_state) ;
134
 
 
135
 
        return max ;
136
 
} /* get_signal_max */
137
 
 
138
 
static double
139
 
calc_decibels (SF_INFO * sfinfo, double max)
140
 
{       double decibels ;
141
 
 
142
 
        switch (sfinfo->format & SF_FORMAT_SUBMASK)
143
 
        {       case SF_FORMAT_PCM_U8 :
144
 
                case SF_FORMAT_PCM_S8 :
145
 
                        decibels = max / 0x80 ;
146
 
                        break ;
147
 
 
148
 
                case SF_FORMAT_PCM_16 :
149
 
                        decibels = max / 0x8000 ;
150
 
                        break ;
151
 
 
152
 
                case SF_FORMAT_PCM_24 :
153
 
                        decibels = max / 0x800000 ;
154
 
                        break ;
155
 
 
156
 
                case SF_FORMAT_PCM_32 :
157
 
                        decibels = max / 0x80000000 ;
158
 
                        break ;
159
 
 
160
 
                case SF_FORMAT_FLOAT :
161
 
                case SF_FORMAT_DOUBLE :
162
 
                        decibels = max / 1.0 ;
163
 
                        break ;
164
 
 
165
 
                default :
166
 
                        decibels = max / 0x8000 ;
167
 
                        break ;
168
 
                } ;
169
 
 
170
 
        return 20.0 * log10 (decibels) ;
171
 
} /* calc_decibels */
172
 
 
173
 
static const char *
174
 
generate_duration_str (SF_INFO *sfinfo)
175
 
{       static char str [128] ;
176
 
 
177
 
        int seconds ;
178
 
 
179
 
        memset (str, 0, sizeof (str)) ;
180
 
 
181
 
        if (sfinfo->samplerate < 1)
182
 
                return NULL ;
183
 
 
184
 
        if (sfinfo->frames / sfinfo->samplerate > 0x7FFFFFFF)
185
 
                return "unknown" ;
186
 
 
187
 
        seconds = sfinfo->frames / sfinfo->samplerate ;
188
 
 
189
 
        snprintf (str, sizeof (str) - 1, "%02d:", seconds / 60 / 60) ;
190
 
 
191
 
        seconds = seconds % (60 * 60) ;
192
 
        snprintf (str + strlen (str), sizeof (str) - strlen (str) - 1, "%02d:", seconds / 60) ;
193
 
 
194
 
        seconds = seconds % 60 ;
195
 
        snprintf (str + strlen (str), sizeof (str) - strlen (str) - 1, "%02d.", seconds) ;
196
 
 
197
 
        seconds = ((1000 * sfinfo->frames) / sfinfo->samplerate) % 1000 ;
198
 
        snprintf (str + strlen (str), sizeof (str) - strlen (str) - 1, "%03d", seconds) ;
199
 
 
200
 
        return str ;
201
 
} /* generate_duration_str */
202
 
 
203
 
static void
204
 
info_dump (const char *filename)
205
 
{       static  char    strbuffer [BUFFER_LEN] ;
206
 
        SNDFILE         *file ;
207
 
        SF_INFO         sfinfo ;
208
 
        double          signal_max, decibels ;
209
 
 
210
 
        sfinfo.format = 0 ;
211
 
 
212
 
        file = sf_open (filename, SFM_READ, &sfinfo) ;
213
 
 
214
 
        printf ("========================================\n") ;
215
 
        sf_command (file, SFC_GET_LOG_INFO, strbuffer, BUFFER_LEN) ;
216
 
        puts (strbuffer) ;
217
 
        printf ("----------------------------------------\n") ;
218
 
 
219
 
        if (file == NULL)
220
 
        {       printf ("Error : Not able to open input file %s.\n", filename) ;
221
 
                fflush (stdout) ;
222
 
                memset (data, 0, sizeof (data)) ;
223
 
                puts (sf_strerror (NULL)) ;
224
 
                }
225
 
        else
226
 
        {       printf ("Sample Rate : %d\n", sfinfo.samplerate) ;
227
 
                if (sfinfo.frames > 0x7FFFFFFF)
228
 
                        printf ("Frames      : unknown\n") ;
229
 
                else
230
 
                        printf ("Frames      : %ld\n", (long) sfinfo.frames) ;
231
 
                printf ("Channels    : %d\n", sfinfo.channels) ;
232
 
                printf ("Format      : 0x%08X\n", sfinfo.format) ;
233
 
                printf ("Sections    : %d\n", sfinfo.sections) ;
234
 
                printf ("Seekable    : %s\n", (sfinfo.seekable ? "TRUE" : "FALSE")) ;
235
 
                printf ("Duration    : %s\n", generate_duration_str (&sfinfo)) ;
236
 
 
237
 
                /* Do not use sf_signal_max because it doesn work for non-seekable files . */
238
 
                signal_max = get_signal_max (file) ;
239
 
                decibels = calc_decibels (&sfinfo, signal_max) ;
240
 
                printf ("Signal Max  : %g (%4.2f dB)\n\n", signal_max, decibels) ;
241
 
                } ;
242
 
 
243
 
        sf_close (file) ;
244
 
 
245
 
} /* info_dump */
246
 
 
247
 
/*==============================================================================
248
 
**      Dumping of SF_INSTRUMENT data.
249
 
*/
250
 
 
251
 
static const char *
252
 
str_of_type (int mode)
253
 
{       switch (mode)
254
 
        {       case SF_LOOP_NONE : return "none" ;
255
 
                case SF_LOOP_FORWARD : return "fwd " ;
256
 
                case SF_LOOP_BACKWARD : return "back" ;
257
 
                case SF_LOOP_ALTERNATING : return "alt " ;
258
 
                default : break ;
259
 
                } ;
260
 
 
261
 
        return "????" ;
262
 
} /* str_of_mode */
263
 
 
264
 
static void
265
 
instrument_dump (const char *filename)
266
 
{       SNDFILE  *file ;
267
 
        SF_INFO  sfinfo ;
268
 
        SF_INSTRUMENT inst ;
269
 
        int got_inst, k ;
270
 
 
271
 
        if ((file = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
272
 
        {       printf ("Error : Not able to open input file %s.\n", filename) ;
273
 
                fflush (stdout) ;
274
 
                memset (data, 0, sizeof (data)) ;
275
 
                puts (sf_strerror (NULL)) ;
276
 
                return ;
277
 
                } ;
278
 
 
279
 
        got_inst = sf_command (file, SFC_GET_INSTRUMENT, &inst, sizeof (inst)) ;
280
 
        sf_close (file) ;
281
 
 
282
 
        if (got_inst == SF_FALSE)
283
 
        {       printf ("Error : File '%s' does not contain instrument data.\n\n", filename) ;
284
 
                return ;
285
 
                } ;
286
 
 
287
 
        printf ("Instrument : %s\n\n", filename) ;
288
 
        printf ("  Gain        : %d\n", inst.gain) ;
289
 
        printf ("  Base note   : %d\n", inst.basenote) ;
290
 
        printf ("  Velocity    : %d - %d\n", (int) inst.velocity_lo, (int) inst.velocity_hi) ;
291
 
        printf ("  Key         : %d - %d\n", (int) inst.key_lo, (int) inst.key_hi) ;
292
 
        printf ("  Loop points : %d\n", inst.loop_count) ;
293
 
 
294
 
        for (k = 0 ; k < inst.loop_count ; k++)
295
 
                printf ("  %-2d    Mode : %s    Start : %6d   End : %6d   Count : %6d\n", k, str_of_type (inst.loops [k].mode), inst.loops [k].start, inst.loops [k].end, inst.loops [k].count) ;
296
 
 
297
 
        putchar ('\n') ;
298
 
} /* instrument_dump */
299
 
 
300
 
static void
301
 
broadcast_dump (const char *filename)
302
 
{       SNDFILE  *file ;
303
 
        SF_INFO  sfinfo ;
304
 
        SF_BROADCAST_INFO bext ;
305
 
        int got_bext ;
306
 
 
307
 
        if ((file = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
308
 
        {       printf ("Error : Not able to open input file %s.\n", filename) ;
309
 
                fflush (stdout) ;
310
 
                memset (data, 0, sizeof (data)) ;
311
 
                puts (sf_strerror (NULL)) ;
312
 
                return ;
313
 
                } ;
314
 
 
315
 
        memset (&bext, 0, sizeof (SF_BROADCAST_INFO)) ;
316
 
 
317
 
        got_bext = sf_command (file, SFC_GET_BROADCAST_INFO, &bext, sizeof (bext)) ;
318
 
        sf_close (file) ;
319
 
 
320
 
        if (got_bext == SF_FALSE)
321
 
        {       printf ("Error : File '%s' does not contain broadcast information.\n\n", filename) ;
322
 
                return ;
323
 
                } ;
324
 
 
325
 
        printf ("Description      : %.*s\n", sizeof (bext.description), bext.description) ;
326
 
        printf ("Originator       : %.*s\n", sizeof (bext.originator), bext.originator) ;
327
 
        printf ("Origination ref  :  %.*s\n", sizeof (bext.originator_reference), bext.originator_reference) ;
328
 
        printf ("Origination date : %.*s\n", sizeof (bext.origination_date), bext.origination_date) ;
329
 
        printf ("Origination time : %.*s\n", sizeof (bext.origination_time), bext.origination_time) ;
330
 
        printf ("BWF version      : %d\n", bext.version) ;
331
 
        printf ("UMID             : %.*s\n", sizeof (bext.umid), bext.umid) ;
332
 
        printf ("Coding history   : %.*s\n", bext.coding_history_size, bext.coding_history) ;
333
 
 
334
 
} /* broadcast_dump */
335
 
 
336
 
/*
337
 
** Do not edit or modify anything in this comment block.
338
 
** The arch-tag line is a file identity tag for the GNU Arch
339
 
** revision control system.
340
 
**
341
 
** arch-tag: f59a05db-a182-41de-aedd-d717ce2bb099
342
 
*/