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