annotate src/libsndfile-1.0.27/programs/sndfile-info.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 1df64224f5ac
children
rev   line source
Chris@40 1 /*
Chris@40 2 ** Copyright (C) 1999-2014 Erik de Castro Lopo <erikd@mega-nerd.com>
Chris@40 3 **
Chris@40 4 ** All rights reserved.
Chris@40 5 **
Chris@40 6 ** Redistribution and use in source and binary forms, with or without
Chris@40 7 ** modification, are permitted provided that the following conditions are
Chris@40 8 ** met:
Chris@40 9 **
Chris@40 10 ** * Redistributions of source code must retain the above copyright
Chris@40 11 ** notice, this list of conditions and the following disclaimer.
Chris@40 12 ** * Redistributions in binary form must reproduce the above copyright
Chris@40 13 ** notice, this list of conditions and the following disclaimer in
Chris@40 14 ** the documentation and/or other materials provided with the
Chris@40 15 ** distribution.
Chris@40 16 ** * Neither the author nor the names of any contributors may be used
Chris@40 17 ** to endorse or promote products derived from this software without
Chris@40 18 ** specific prior written permission.
Chris@40 19 **
Chris@40 20 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Chris@40 21 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
Chris@40 22 ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
Chris@40 23 ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
Chris@40 24 ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Chris@40 25 ** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
Chris@40 26 ** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
Chris@40 27 ** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
Chris@40 28 ** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
Chris@40 29 ** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
Chris@40 30 ** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Chris@40 31 */
Chris@40 32
Chris@40 33 #include <stdio.h>
Chris@40 34 #include <stdlib.h>
Chris@40 35 #include <string.h>
Chris@40 36 #include <inttypes.h>
Chris@40 37 #include <ctype.h>
Chris@40 38 #include <math.h>
Chris@40 39
Chris@40 40 #include <sndfile.h>
Chris@40 41
Chris@40 42 #include "common.h"
Chris@40 43
Chris@40 44 #define BUFFER_LEN (1 << 16)
Chris@40 45
Chris@40 46 #if (defined (WIN32) || defined (_WIN32))
Chris@40 47 #include <windows.h>
Chris@40 48 #endif
Chris@40 49
Chris@40 50 static void usage_exit (const char *progname) ;
Chris@40 51
Chris@40 52 static void info_dump (const char *filename) ;
Chris@40 53 static int instrument_dump (const char *filename) ;
Chris@40 54 static int broadcast_dump (const char *filename) ;
Chris@40 55 static int chanmap_dump (const char *filename) ;
Chris@40 56 static int cart_dump (const char *filename) ;
Chris@40 57 static void total_dump (void) ;
Chris@40 58
Chris@40 59 static double total_seconds = 0.0 ;
Chris@40 60
Chris@40 61 int
Chris@40 62 main (int argc, char *argv [])
Chris@40 63 { int k ;
Chris@40 64
Chris@40 65 if (argc < 2 || strcmp (argv [1], "--help") == 0 || strcmp (argv [1], "-h") == 0)
Chris@40 66 usage_exit (program_name (argv [0])) ;
Chris@40 67
Chris@40 68 if (strcmp (argv [1], "--instrument") == 0)
Chris@40 69 { int error = 0 ;
Chris@40 70
Chris@40 71 for (k = 2 ; k < argc ; k++)
Chris@40 72 error += instrument_dump (argv [k]) ;
Chris@40 73 return error ;
Chris@40 74 } ;
Chris@40 75
Chris@40 76 if (strcmp (argv [1], "--broadcast") == 0)
Chris@40 77 { int error = 0 ;
Chris@40 78
Chris@40 79 for (k = 2 ; k < argc ; k++)
Chris@40 80 error += broadcast_dump (argv [k]) ;
Chris@40 81 return error ;
Chris@40 82 } ;
Chris@40 83
Chris@40 84 if (strcmp (argv [1], "--channel-map") == 0)
Chris@40 85 { int error = 0 ;
Chris@40 86
Chris@40 87 for (k = 2 ; k < argc ; k++)
Chris@40 88 error += chanmap_dump (argv [k]) ;
Chris@40 89 return error ;
Chris@40 90 } ;
Chris@40 91
Chris@40 92 if (strcmp (argv [1], "--cart") == 0)
Chris@40 93 { int error = 0 ;
Chris@40 94
Chris@40 95 for (k = 2 ; k < argc ; k++)
Chris@40 96 error += cart_dump (argv [k]) ;
Chris@40 97 return error ;
Chris@40 98 } ;
Chris@40 99
Chris@40 100 for (k = 1 ; k < argc ; k++)
Chris@40 101 info_dump (argv [k]) ;
Chris@40 102
Chris@40 103 if (argc > 2)
Chris@40 104 total_dump () ;
Chris@40 105
Chris@40 106 return 0 ;
Chris@40 107 } /* main */
Chris@40 108
Chris@40 109 /*==============================================================================
Chris@40 110 ** Print version and usage.
Chris@40 111 */
Chris@40 112
Chris@40 113 static double data [BUFFER_LEN] ;
Chris@40 114
Chris@40 115 static void
Chris@40 116 usage_exit (const char *progname)
Chris@40 117 { printf ("Usage :\n %s <file> ...\n", progname) ;
Chris@40 118 printf (" Prints out information about one or more sound files.\n\n") ;
Chris@40 119 printf (" %s --instrument <file>\n", progname) ;
Chris@40 120 printf (" Prints out the instrument data for the given file.\n\n") ;
Chris@40 121 printf (" %s --broadcast <file>\n", progname) ;
Chris@40 122 printf (" Prints out the broadcast WAV info for the given file.\n\n") ;
Chris@40 123 printf (" %s --channel-map <file>\n", progname) ;
Chris@40 124 printf (" Prints out the channel map for the given file.\n\n") ;
Chris@40 125 printf (" %s --cart <file>\n", progname) ;
Chris@40 126 printf (" Prints out the cart chunk WAV info for the given file.\n\n") ;
Chris@40 127
Chris@40 128 printf ("Using %s.\n\n", sf_version_string ()) ;
Chris@40 129 #if (defined (_WIN32) || defined (WIN32))
Chris@40 130 printf ("This is a Unix style command line application which\n"
Chris@40 131 "should be run in a MSDOS box or Command Shell window.\n\n") ;
Chris@40 132 printf ("Sleeping for 5 seconds before exiting.\n\n") ;
Chris@40 133 fflush (stdout) ;
Chris@40 134
Chris@40 135 Sleep (5 * 1000) ;
Chris@40 136 #endif
Chris@40 137 exit (1) ;
Chris@40 138 } /* usage_exit */
Chris@40 139
Chris@40 140 /*==============================================================================
Chris@40 141 ** Dumping of sndfile info.
Chris@40 142 */
Chris@40 143
Chris@40 144 static double data [BUFFER_LEN] ;
Chris@40 145
Chris@40 146 static double
Chris@40 147 calc_decibels (SF_INFO * sfinfo, double max)
Chris@40 148 { double decibels ;
Chris@40 149
Chris@40 150 switch (sfinfo->format & SF_FORMAT_SUBMASK)
Chris@40 151 { case SF_FORMAT_PCM_U8 :
Chris@40 152 case SF_FORMAT_PCM_S8 :
Chris@40 153 decibels = max / 0x80 ;
Chris@40 154 break ;
Chris@40 155
Chris@40 156 case SF_FORMAT_PCM_16 :
Chris@40 157 decibels = max / 0x8000 ;
Chris@40 158 break ;
Chris@40 159
Chris@40 160 case SF_FORMAT_PCM_24 :
Chris@40 161 decibels = max / 0x800000 ;
Chris@40 162 break ;
Chris@40 163
Chris@40 164 case SF_FORMAT_PCM_32 :
Chris@40 165 decibels = max / 0x80000000 ;
Chris@40 166 break ;
Chris@40 167
Chris@40 168 case SF_FORMAT_FLOAT :
Chris@40 169 case SF_FORMAT_DOUBLE :
Chris@40 170 decibels = max / 1.0 ;
Chris@40 171 break ;
Chris@40 172
Chris@40 173 default :
Chris@40 174 decibels = max / 0x8000 ;
Chris@40 175 break ;
Chris@40 176 } ;
Chris@40 177
Chris@40 178 return 20.0 * log10 (decibels) ;
Chris@40 179 } /* calc_decibels */
Chris@40 180
Chris@40 181 static const char *
Chris@40 182 format_duration_str (double seconds)
Chris@40 183 { static char str [128] ;
Chris@40 184 int hrs, min ;
Chris@40 185 double sec ;
Chris@40 186
Chris@40 187 memset (str, 0, sizeof (str)) ;
Chris@40 188
Chris@40 189 hrs = (int) (seconds / 3600.0) ;
Chris@40 190 min = (int) ((seconds - (hrs * 3600.0)) / 60.0) ;
Chris@40 191 sec = seconds - (hrs * 3600.0) - (min * 60.0) ;
Chris@40 192
Chris@40 193 snprintf (str, sizeof (str) - 1, "%02d:%02d:%06.3f", hrs, min, sec) ;
Chris@40 194
Chris@40 195 return str ;
Chris@40 196 } /* format_duration_str */
Chris@40 197
Chris@40 198 static const char *
Chris@40 199 generate_duration_str (SF_INFO *sfinfo)
Chris@40 200 {
Chris@40 201 double seconds ;
Chris@40 202
Chris@40 203 if (sfinfo->samplerate < 1)
Chris@40 204 return NULL ;
Chris@40 205
Chris@40 206 if (sfinfo->frames / sfinfo->samplerate > 0x7FFFFFFF)
Chris@40 207 return "unknown" ;
Chris@40 208
Chris@40 209 seconds = (1.0 * sfinfo->frames) / sfinfo->samplerate ;
Chris@40 210
Chris@40 211 /* Accumulate the total of all known file durations */
Chris@40 212 total_seconds += seconds ;
Chris@40 213
Chris@40 214 return format_duration_str (seconds) ;
Chris@40 215 } /* generate_duration_str */
Chris@40 216
Chris@40 217 static void
Chris@40 218 info_dump (const char *filename)
Chris@40 219 { static char strbuffer [BUFFER_LEN] ;
Chris@40 220 SNDFILE *file ;
Chris@40 221 SF_INFO sfinfo ;
Chris@40 222 double signal_max, decibels ;
Chris@40 223
Chris@40 224 memset (&sfinfo, 0, sizeof (sfinfo)) ;
Chris@40 225
Chris@40 226 if ((file = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
Chris@40 227 { printf ("Error : Not able to open input file %s.\n", filename) ;
Chris@40 228 fflush (stdout) ;
Chris@40 229 memset (data, 0, sizeof (data)) ;
Chris@40 230 sf_command (file, SFC_GET_LOG_INFO, strbuffer, BUFFER_LEN) ;
Chris@40 231 puts (strbuffer) ;
Chris@40 232 puts (sf_strerror (NULL)) ;
Chris@40 233 return ;
Chris@40 234 } ;
Chris@40 235
Chris@40 236 printf ("========================================\n") ;
Chris@40 237 sf_command (file, SFC_GET_LOG_INFO, strbuffer, BUFFER_LEN) ;
Chris@40 238 puts (strbuffer) ;
Chris@40 239 printf ("----------------------------------------\n") ;
Chris@40 240
Chris@40 241 printf ("Sample Rate : %d\n", sfinfo.samplerate) ;
Chris@40 242
Chris@40 243 if (sfinfo.frames == SF_COUNT_MAX)
Chris@40 244 printf ("Frames : unknown\n") ;
Chris@40 245 else
Chris@40 246 printf ("Frames : %" PRId64 "\n", sfinfo.frames) ;
Chris@40 247
Chris@40 248 printf ("Channels : %d\n", sfinfo.channels) ;
Chris@40 249 printf ("Format : 0x%08X\n", sfinfo.format) ;
Chris@40 250 printf ("Sections : %d\n", sfinfo.sections) ;
Chris@40 251 printf ("Seekable : %s\n", (sfinfo.seekable ? "TRUE" : "FALSE")) ;
Chris@40 252 printf ("Duration : %s\n", generate_duration_str (&sfinfo)) ;
Chris@40 253
Chris@40 254 if (sfinfo.frames < 100 * 1024 * 1024)
Chris@40 255 { /* Do not use sf_signal_max because it doesn't work for non-seekable files . */
Chris@40 256 sf_command (file, SFC_CALC_SIGNAL_MAX, &signal_max, sizeof (signal_max)) ;
Chris@40 257 decibels = calc_decibels (&sfinfo, signal_max) ;
Chris@40 258 printf ("Signal Max : %g (%4.2f dB)\n", signal_max, decibels) ;
Chris@40 259 } ;
Chris@40 260 putchar ('\n') ;
Chris@40 261
Chris@40 262 sf_close (file) ;
Chris@40 263
Chris@40 264 } /* info_dump */
Chris@40 265
Chris@40 266 /*==============================================================================
Chris@40 267 ** Dumping of SF_INSTRUMENT data.
Chris@40 268 */
Chris@40 269
Chris@40 270 static const char *
Chris@40 271 str_of_type (int mode)
Chris@40 272 { switch (mode)
Chris@40 273 { case SF_LOOP_NONE : return "none" ;
Chris@40 274 case SF_LOOP_FORWARD : return "fwd " ;
Chris@40 275 case SF_LOOP_BACKWARD : return "back" ;
Chris@40 276 case SF_LOOP_ALTERNATING : return "alt " ;
Chris@40 277 default : break ;
Chris@40 278 } ;
Chris@40 279
Chris@40 280 return "????" ;
Chris@40 281 } /* str_of_mode */
Chris@40 282
Chris@40 283 static int
Chris@40 284 instrument_dump (const char *filename)
Chris@40 285 { SNDFILE *file ;
Chris@40 286 SF_INFO sfinfo ;
Chris@40 287 SF_INSTRUMENT inst ;
Chris@40 288 int got_inst, k ;
Chris@40 289
Chris@40 290 memset (&sfinfo, 0, sizeof (sfinfo)) ;
Chris@40 291
Chris@40 292 if ((file = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
Chris@40 293 { printf ("Error : Not able to open input file %s.\n", filename) ;
Chris@40 294 fflush (stdout) ;
Chris@40 295 memset (data, 0, sizeof (data)) ;
Chris@40 296 puts (sf_strerror (NULL)) ;
Chris@40 297 return 1 ;
Chris@40 298 } ;
Chris@40 299
Chris@40 300 got_inst = sf_command (file, SFC_GET_INSTRUMENT, &inst, sizeof (inst)) ;
Chris@40 301 sf_close (file) ;
Chris@40 302
Chris@40 303 if (got_inst == SF_FALSE)
Chris@40 304 { printf ("Error : File '%s' does not contain instrument data.\n\n", filename) ;
Chris@40 305 return 1 ;
Chris@40 306 } ;
Chris@40 307
Chris@40 308 printf ("Instrument : %s\n\n", filename) ;
Chris@40 309 printf (" Gain : %d\n", inst.gain) ;
Chris@40 310 printf (" Base note : %d\n", inst.basenote) ;
Chris@40 311 printf (" Velocity : %d - %d\n", (int) inst.velocity_lo, (int) inst.velocity_hi) ;
Chris@40 312 printf (" Key : %d - %d\n", (int) inst.key_lo, (int) inst.key_hi) ;
Chris@40 313 printf (" Loop points : %d\n", inst.loop_count) ;
Chris@40 314
Chris@40 315 for (k = 0 ; k < inst.loop_count ; k++)
Chris@40 316 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) ;
Chris@40 317
Chris@40 318 putchar ('\n') ;
Chris@40 319 return 0 ;
Chris@40 320 } /* instrument_dump */
Chris@40 321
Chris@40 322 static int
Chris@40 323 broadcast_dump (const char *filename)
Chris@40 324 { SNDFILE *file ;
Chris@40 325 SF_INFO sfinfo ;
Chris@40 326 SF_BROADCAST_INFO_2K bext ;
Chris@40 327 double time_ref_sec ;
Chris@40 328 int got_bext ;
Chris@40 329
Chris@40 330 memset (&sfinfo, 0, sizeof (sfinfo)) ;
Chris@40 331
Chris@40 332 if ((file = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
Chris@40 333 { printf ("Error : Not able to open input file %s.\n", filename) ;
Chris@40 334 fflush (stdout) ;
Chris@40 335 memset (data, 0, sizeof (data)) ;
Chris@40 336 puts (sf_strerror (NULL)) ;
Chris@40 337 return 1 ;
Chris@40 338 } ;
Chris@40 339
Chris@40 340 memset (&bext, 0, sizeof (SF_BROADCAST_INFO_2K)) ;
Chris@40 341
Chris@40 342 got_bext = sf_command (file, SFC_GET_BROADCAST_INFO, &bext, sizeof (bext)) ;
Chris@40 343 sf_close (file) ;
Chris@40 344
Chris@40 345 if (got_bext == SF_FALSE)
Chris@40 346 { printf ("Error : File '%s' does not contain broadcast information.\n\n", filename) ;
Chris@40 347 return 1 ;
Chris@40 348 } ;
Chris@40 349
Chris@40 350 /*
Chris@40 351 ** From : http://www.ebu.ch/en/technical/publications/userguides/bwf_user_guide.php
Chris@40 352 **
Chris@40 353 ** Time Reference:
Chris@40 354 ** This field is a count from midnight in samples to the first sample
Chris@40 355 ** of the audio sequence.
Chris@40 356 */
Chris@40 357
Chris@40 358 time_ref_sec = ((pow (2.0, 32) * bext.time_reference_high) + (1.0 * bext.time_reference_low)) / sfinfo.samplerate ;
Chris@40 359
Chris@40 360 printf ("Description : %.*s\n", (int) sizeof (bext.description), bext.description) ;
Chris@40 361 printf ("Originator : %.*s\n", (int) sizeof (bext.originator), bext.originator) ;
Chris@40 362 printf ("Origination ref : %.*s\n", (int) sizeof (bext.originator_reference), bext.originator_reference) ;
Chris@40 363 printf ("Origination date : %.*s\n", (int) sizeof (bext.origination_date), bext.origination_date) ;
Chris@40 364 printf ("Origination time : %.*s\n", (int) sizeof (bext.origination_time), bext.origination_time) ;
Chris@40 365
Chris@40 366 if (bext.time_reference_high == 0 && bext.time_reference_low == 0)
Chris@40 367 printf ("Time ref : 0\n") ;
Chris@40 368 else
Chris@40 369 printf ("Time ref : 0x%x%08x (%.6f seconds)\n", bext.time_reference_high, bext.time_reference_low, time_ref_sec) ;
Chris@40 370
Chris@40 371 printf ("BWF version : %d\n", bext.version) ;
Chris@40 372 printf ("UMID : %.*s\n", (int) sizeof (bext.umid), bext.umid) ;
Chris@40 373 printf ("Coding history : %.*s\n", bext.coding_history_size, bext.coding_history) ;
Chris@40 374
Chris@40 375 return 0 ;
Chris@40 376 } /* broadcast_dump */
Chris@40 377
Chris@40 378 static int
Chris@40 379 chanmap_dump (const char *filename)
Chris@40 380 { SNDFILE *file ;
Chris@40 381 SF_INFO sfinfo ;
Chris@40 382 int * channel_map ;
Chris@40 383 int got_chanmap, k ;
Chris@40 384
Chris@40 385 memset (&sfinfo, 0, sizeof (sfinfo)) ;
Chris@40 386
Chris@40 387 if ((file = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
Chris@40 388 { printf ("Error : Not able to open input file %s.\n", filename) ;
Chris@40 389 fflush (stdout) ;
Chris@40 390 memset (data, 0, sizeof (data)) ;
Chris@40 391 puts (sf_strerror (NULL)) ;
Chris@40 392 return 1 ;
Chris@40 393 } ;
Chris@40 394
Chris@40 395 if ((channel_map = calloc (sfinfo.channels, sizeof (int))) == NULL)
Chris@40 396 { printf ("Error : malloc failed.\n\n") ;
Chris@40 397 return 1 ;
Chris@40 398 } ;
Chris@40 399
Chris@40 400 got_chanmap = sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map, sfinfo.channels * sizeof (int)) ;
Chris@40 401 sf_close (file) ;
Chris@40 402
Chris@40 403 if (got_chanmap == SF_FALSE)
Chris@40 404 { printf ("Error : File '%s' does not contain channel map information.\n\n", filename) ;
Chris@40 405 free (channel_map) ;
Chris@40 406 return 1 ;
Chris@40 407 } ;
Chris@40 408
Chris@40 409 printf ("File : %s\n\n", filename) ;
Chris@40 410
Chris@40 411 puts (" Chan Position") ;
Chris@40 412 for (k = 0 ; k < sfinfo.channels ; k ++)
Chris@40 413 { const char * name ;
Chris@40 414
Chris@40 415 #define CASE_NAME(x) case x : name = #x ; break ;
Chris@40 416 switch (channel_map [k])
Chris@40 417 { CASE_NAME (SF_CHANNEL_MAP_INVALID) ;
Chris@40 418 CASE_NAME (SF_CHANNEL_MAP_MONO) ;
Chris@40 419 CASE_NAME (SF_CHANNEL_MAP_LEFT) ;
Chris@40 420 CASE_NAME (SF_CHANNEL_MAP_RIGHT) ;
Chris@40 421 CASE_NAME (SF_CHANNEL_MAP_CENTER) ;
Chris@40 422 CASE_NAME (SF_CHANNEL_MAP_FRONT_LEFT) ;
Chris@40 423 CASE_NAME (SF_CHANNEL_MAP_FRONT_RIGHT) ;
Chris@40 424 CASE_NAME (SF_CHANNEL_MAP_FRONT_CENTER) ;
Chris@40 425 CASE_NAME (SF_CHANNEL_MAP_REAR_CENTER) ;
Chris@40 426 CASE_NAME (SF_CHANNEL_MAP_REAR_LEFT) ;
Chris@40 427 CASE_NAME (SF_CHANNEL_MAP_REAR_RIGHT) ;
Chris@40 428 CASE_NAME (SF_CHANNEL_MAP_LFE) ;
Chris@40 429 CASE_NAME (SF_CHANNEL_MAP_FRONT_LEFT_OF_CENTER) ;
Chris@40 430 CASE_NAME (SF_CHANNEL_MAP_FRONT_RIGHT_OF_CENTER) ;
Chris@40 431 CASE_NAME (SF_CHANNEL_MAP_SIDE_LEFT) ;
Chris@40 432 CASE_NAME (SF_CHANNEL_MAP_SIDE_RIGHT) ;
Chris@40 433 CASE_NAME (SF_CHANNEL_MAP_TOP_CENTER) ;
Chris@40 434 CASE_NAME (SF_CHANNEL_MAP_TOP_FRONT_LEFT) ;
Chris@40 435 CASE_NAME (SF_CHANNEL_MAP_TOP_FRONT_RIGHT) ;
Chris@40 436 CASE_NAME (SF_CHANNEL_MAP_TOP_FRONT_CENTER) ;
Chris@40 437 CASE_NAME (SF_CHANNEL_MAP_TOP_REAR_LEFT) ;
Chris@40 438 CASE_NAME (SF_CHANNEL_MAP_TOP_REAR_RIGHT) ;
Chris@40 439 CASE_NAME (SF_CHANNEL_MAP_TOP_REAR_CENTER) ;
Chris@40 440 CASE_NAME (SF_CHANNEL_MAP_MAX) ;
Chris@40 441 default : name = "default" ;
Chris@40 442 break ;
Chris@40 443 } ;
Chris@40 444
Chris@40 445 printf (" %3d %s\n", k, name) ;
Chris@40 446 } ;
Chris@40 447
Chris@40 448 putchar ('\n') ;
Chris@40 449 free (channel_map) ;
Chris@40 450
Chris@40 451 return 0 ;
Chris@40 452 } /* chanmap_dump */
Chris@40 453
Chris@40 454 static int
Chris@40 455 cart_dump (const char *filename)
Chris@40 456 { SNDFILE *file ;
Chris@40 457 SF_INFO sfinfo ;
Chris@40 458 SF_CART_INFO_VAR (1024) cart ;
Chris@40 459 int got_cart, k ;
Chris@40 460
Chris@40 461 memset (&sfinfo, 0, sizeof (sfinfo)) ;
Chris@40 462 memset (&cart, 0, sizeof (cart)) ;
Chris@40 463
Chris@40 464 if ((file = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
Chris@40 465 { printf ("Error : Not able to open input file %s.\n", filename) ;
Chris@40 466 fflush (stdout) ;
Chris@40 467 memset (data, 0, sizeof (data)) ;
Chris@40 468 puts (sf_strerror (NULL)) ;
Chris@40 469 return 1 ;
Chris@40 470 } ;
Chris@40 471
Chris@40 472 got_cart = sf_command (file, SFC_GET_CART_INFO, &cart, sizeof (cart)) ;
Chris@40 473 sf_close (file) ;
Chris@40 474
Chris@40 475 if (got_cart == SF_FALSE)
Chris@40 476 { printf ("Error : File '%s' does not contain cart information.\n\n", filename) ;
Chris@40 477 return 1 ;
Chris@40 478 } ;
Chris@40 479
Chris@40 480 printf ("Version : %.*s\n", (int) sizeof (cart.version), cart.version) ;
Chris@40 481 printf ("Title : %.*s\n", (int) sizeof (cart.title), cart.title) ;
Chris@40 482 printf ("Artist : %.*s\n", (int) sizeof (cart.artist), cart.artist) ;
Chris@40 483 printf ("Cut id : %.*s\n", (int) sizeof (cart.cut_id), cart.cut_id) ;
Chris@40 484 printf ("Category : %.*s\n", (int) sizeof (cart.category), cart.category) ;
Chris@40 485 printf ("Classification : %.*s\n", (int) sizeof (cart.classification), cart.classification) ;
Chris@40 486 printf ("Out cue : %.*s\n", (int) sizeof (cart.out_cue), cart.out_cue) ;
Chris@40 487 printf ("Start date : %.*s\n", (int) sizeof (cart.start_date), cart.start_date) ;
Chris@40 488 printf ("Start time : %.*s\n", (int) sizeof (cart.start_time), cart.start_time) ;
Chris@40 489 printf ("End date : %.*s\n", (int) sizeof (cart.end_date), cart.end_date) ;
Chris@40 490 printf ("End time : %.*s\n", (int) sizeof (cart.end_time), cart.end_time) ;
Chris@40 491 printf ("App id : %.*s\n", (int) sizeof (cart.producer_app_id), cart.producer_app_id) ;
Chris@40 492 printf ("App version : %.*s\n", (int) sizeof (cart.producer_app_version), cart.producer_app_version) ;
Chris@40 493 printf ("User defined : %.*s\n", (int) sizeof (cart.user_def), cart.user_def) ;
Chris@40 494 printf ("Level ref. : %d\n", cart.level_reference) ;
Chris@40 495 printf ("Post timers :\n") ;
Chris@40 496
Chris@40 497 for (k = 0 ; k < ARRAY_LEN (cart.post_timers) ; k++)
Chris@40 498 if (cart.post_timers [k].usage [0])
Chris@40 499 printf (" %d %.*s %d\n", k, (int) sizeof (cart.post_timers [k].usage), cart.post_timers [k].usage, cart.post_timers [k].value) ;
Chris@40 500
Chris@40 501 printf ("Reserved : %.*s\n", (int) sizeof (cart.reserved), cart.reserved) ;
Chris@40 502 printf ("Url : %.*s\n", (int) sizeof (cart.url), cart.url) ;
Chris@40 503 printf ("Tag text : %.*s\n", cart.tag_text_size, cart.tag_text) ;
Chris@40 504
Chris@40 505 return 0 ;
Chris@40 506 } /* cart_dump */
Chris@40 507
Chris@40 508 static void
Chris@40 509 total_dump (void)
Chris@40 510 { printf ("========================================\n") ;
Chris@40 511 printf ("Total Duration : %s\n", format_duration_str (total_seconds)) ;
Chris@40 512 } /* total_dump */