shithub: sox

Download patch

ref: b7a1855e6660d284b290535c2850272fc785d34e
parent: fb6af3a1690d434f6465e393730bf89c108acabd
author: robs <robs>
date: Sat Feb 9 14:18:33 EST 2008

sexy soxi

--- a/AUTHORS
+++ b/AUTHORS
@@ -21,7 +21,7 @@
 		flanger, soft-knee companding, speed via resampling, filters
 		makeover inc. gnuplot & octave plotting, splice, remix;
 		new effects chain with buffering and any # channels.
-                Others: open input files via URL, file merging, play
+                Others: soxi, open input files via URL, file merging, play
                 multiple files with mixed format types, play with replay-gain,
                 building with cmake, much manual improvement and expansion,
                 various fixes, enhancements and clean-ups.
--- a/ChangeLog
+++ b/ChangeLog
@@ -19,6 +19,7 @@
 Other new features:
 
   o Command line support for multiple file comments.  (robs)
+  o Added soxi utility to extract/display file header fields.  (robs)
 
 Bug fixes:
 
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,8 +9,8 @@
 
 # man pages are not considered to be sources, so need to add "dist_"
 # prefix to ensure they are added to the distribution.
-dist_man_MANS = sox.1 soxeffect.7 soxformat.7 soxexam.7 libsox.3
-EXTRA_DIST = sox.txt soxeffect.txt soxformat.txt soxexam.txt libsox.txt CMakeLists.txt
+dist_man_MANS = sox.1 soxi.1 soxeffect.7 soxformat.7 soxexam.7 libsox.3
+EXTRA_DIST = sox.txt soxi.txt soxeffect.txt soxformat.txt soxexam.txt libsox.txt CMakeLists.txt
 
 play.1 rec.1: sox.1
 	$(RM) $@ && $(LN_S) $< $@
@@ -19,13 +19,13 @@
 .1.txt .3.txt .7.txt:
 	tbl $(srcdir)/$< | nroff -man | col -b > $@
 
-txt: sox.txt soxeffect.txt soxformat.txt soxexam.txt libsox.txt
+txt: sox.txt soxi.txt soxeffect.txt soxformat.txt soxexam.txt libsox.txt
 
 # Rule for making PDF man pages
 .1.pdf .3.pdf .7.pdf:
 	tbl $(srcdir)/$< | groff -man -Tps | ps2pdf - $@
 
-pdf: sox.pdf soxeffect.pdf soxformat.pdf soxexam.pdf libsox.pdf
+pdf: sox.pdf soxi.pdf soxeffect.pdf soxformat.pdf soxexam.pdf libsox.pdf
 
 install-data-hook:
 	cd $(DESTDIR)$(mandir)/man1 && $(RM) play.1 && $(LN_S) sox.1 play.1
--- a/sox.1
+++ b/sox.1
@@ -172,6 +172,10 @@
 case, if anything other than a simple format conversion was performed
 then the output file Replay Gain information is likely to be incorrect
 and so should be recalculated using a tool that supports this (not SoX).
+.SP
+The
+.BR soxi (1)
+command can be used to display information from audio file headers.
 .SS Determining & Setting The File Format
 There are several mechanisms available for SoX to use to determine or set the
 format characteristics of an audio file.  Depending on the circumstances,
@@ -420,16 +424,6 @@
 is by default 44\*d1\ kHz, but, as with a normal
 file, this can be overridden if desired using command-line format
 options (see below).
-.SP
-One other use of \fB\-n\fR is to use it in conjunction with
-.B \-V
-to display information from the audio file header
-without having to read any further into the file, e.g.
-.EX
-	sox \-V *.wav \-n
-.EE
-will display header information for each `WAV' file in the current
-directory.
 .TP
 \fB\-e\fR
 This is an alias of
@@ -739,6 +733,7 @@
 Please report any bugs found in this version of SoX to the mailing list
 (sox-users@lists.sourceforge.net).
 .SH SEE ALSO
+.BR soxi (1),
 .BR soxexam (7),
 .BR soxformat (7),
 .BR soxeffect (7),
--- a/soxeffect.7
+++ b/soxeffect.7
@@ -775,7 +775,7 @@
 channels are involved, a script such as the following is useful:
 .EX
 #!/bin/sh                        # This is a Bourne shell script
-chans=$(sox -V "$1" -n 2>&1|grep \^Chan|head -1|sed "s/.*: //")
+chans=$(soxi -c "$1")
 while [ $chans -ge 1 ]; do
   chans0=$(printf %02i $chans)   # 2 digits hence up to 99 chans
   out=$(echo "$1"|sed "s/\\(.*\\)\\.\\(.*\\)/\\1-$chans0.\\2/")
@@ -793,7 +793,9 @@
 .SP
 See also
 .B mixer
-for a similar effect.
+and
+.B swap
+for similar effects.
 .TP
 \fBrepeat \fIcount\fR
 Repeat the entire audio \fIcount\fR times.
@@ -1444,10 +1446,10 @@
 effect.  It differs in that the depth parameter ranges from 0 to 1 and defaults to 0\*d5.
 .SH SEE ALSO
 .BR sox (1),
+.BR soxi (1),
 .BR soxformat (7),
 .BR libsox (3),
-.BR soxexam (7),
-.BR wget (1)
+.BR soxexam (7)
 .SP
 The SoX web page at http://sox.sourceforge.net
 .SS References
--- a/soxexam.7
+++ b/soxexam.7
@@ -384,6 +384,7 @@
 download from the SoX web-site [1].
 .SH SEE ALSO
 .BR sox (1),
+.BR soxi (1),
 .BR libsox (3)
 .SS References
 .TP
--- a/soxformat.7
+++ b/soxformat.7
@@ -588,6 +588,7 @@
 Fasttracker 2 Extended Instrument format.
 .SH SEE ALSO
 .BR sox (1),
+.BR soxi (1),
 .BR soxeffect (7),
 .BR libsox (3),
 .BR octave (1),
--- /dev/null
+++ b/soxi.1
@@ -1,0 +1,96 @@
+'\" t
+'\" The line above instructs most `man' programs to invoke tbl
+'\"
+'\" Separate paragraphs; not the same as PP which resets indent level.
+.de SP
+.if t .sp .5
+.if n .sp
+..
+'\"
+'\" Replacement em-dash for nroff (default is too short).
+.ie n .ds m " - 
+.el .ds m \(em
+'\"
+'\" Placeholder macro for if longer nroff arrow is needed.
+.ds RA \(->
+'\"
+'\" Decimal point set slightly raised
+.if t .ds d \v'-.15m'.\v'+.15m'
+.if n .ds d .
+'\"
+'\" Enclosure macro for examples
+.de EX
+.SP
+.nf
+.ft CW
+..
+.de EE
+.ft R
+.SP
+.fi
+..
+.TH SoX 1 "February 9, 2008" "soxi" "Sound eXchange"
+.SH NAME
+SoX \- Sound eXchange, the Swiss Army knife of audio manipulation
+.SH SYNOPSIS
+\fBsoxi\fR [\fB\-r\fR\^|\^\fB\-c\fR\^|\^\fB\-s\fR\^|\^\fB\-d\fR\^|\^\fB\-b\fR\^|\^\fB\-e\fR\^|\^\fB\-a\fR] \fIinfile1\fR ...
+.SH DESCRIPTION
+Displays information from the header of a given audio file or files.
+Supported audio file types are listed and described in
+.BR soxformat (7).
+Note however, that
+.B soxi
+is intended for use only with audio files with a self-describing header.
+.SP
+By default, as much information as is available is shown.
+The options below may be used to select a single piece of information to show.
+.SH OPTIONS
+.TP
+\fB\-r\fR
+Show sample-rate.
+.TP
+\fB\-c\fR
+Show number of channels.
+.TP
+\fB\-s\fR
+Show number of samples (0 if unavailable).
+.TP
+\fB\-d\fR
+Show duration in minutes and seconds (0 if unavailable).
+Equivalent to number of samples divided by the sample-rate.
+.TP
+\fB\-b\fR
+Show number of bits per sample.
+.TP
+\fB\-e\fR
+Show the name of the audio encoding.
+.TP
+\fB\-a\fR
+Show file comments (annotations) if available.
+.SH BUGS
+Please report any bugs found in this version of SoX to the mailing list
+(sox-users@lists.sourceforge.net).
+.SH SEE ALSO
+.BR sox (1),
+.BR soxformat (7),
+.BR soxeffect (7),
+.BR soxexam (7),
+.BR libsox (3)
+.SP
+The SoX web site at http://sox.sourceforge.net
+.SH LICENSE
+Copyright 2008 by Chris Bagwell and SoX Contributors.
+.SP
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+.SP
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+.SH AUTHORS
+Chris Bagwell (cbagwell@users.sourceforge.net).
+Other authors and contributors are listed in the AUTHORS file that
+is distributed with the source code.
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -56,6 +56,7 @@
 if (LN)
   add_custom_target(rec ALL ${LN} -sf sox rec DEPENDS sox)
   add_custom_target(play ALL ${LN} -sf sox play DEPENDS sox)
+  add_custom_target(soxi ALL ${LN} -sf sox soxi DEPENDS sox)
 endif (LN)
 find_program(CTAGS NAMES exuberant-ctags ctags)
 add_custom_target(tags ${CTAGS} --recurse --extra=fq ${CMAKE_CURRENT_SOURCE_DIR})
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -288,19 +288,19 @@
 
 EXTRA_DIST = tests.sh testall.sh tests.bat testall.bat monkey.au monkey.wav sox_sample_test.c amr-wb-test CMakeLists.txt soxstdint.h.cmake soxconfig.h.cmake example1.c test-comments
 
-all: sox$(EXEEXT) play rec sox_sample_test$(EXEEXT) example1$(EXEEXT)
+all: sox$(EXEEXT) play rec soxi sox_sample_test$(EXEEXT) example1$(EXEEXT)
 
-play rec: sox$(EXEEXT)
+play rec soxi: sox$(EXEEXT)
 	./sox --help > /dev/null
 	test -f .libs/lt-sox && ( $(RM) $@ && $(LN_S) .libs/lt-sox $@ ) || $(LN_S) sox$(EXEEXT) $@
 
 install-exec-hook:
 	if test "$(PLAYRECLINKS)" = "yes"; then	\
-		cd $(DESTDIR)$(bindir); $(RM) play rec; $(LN_S) sox play; $(LN_S) sox rec; \
+		cd $(DESTDIR)$(bindir); $(RM) play rec soxi; $(LN_S) sox play; $(LN_S) sox rec; $(LN_S) sox soxi; \
 	fi
 
 clean-local:
-	$(RM) play rec
+	$(RM) play rec soxi
 	$(RM) sox_sample_test
 	$(RM) example1
 
--- a/src/sox.c
+++ b/src/sox.c
@@ -66,7 +66,7 @@
 /* argv[0] options */
 
 static char const * myname = NULL;
-static sox_bool play = sox_false, rec = sox_false;
+static enum {sox_sox, sox_play, sox_rec, sox_soxi} sox_mode;
 
 
 /* gopts */
@@ -255,7 +255,7 @@
     fprintf(stderr, "Failed: %s\n\n", message);  /* N.B. stderr */
 
   printf("Usage summary: [gopts] [[fopts] infile]... [fopts]%s [effect [effopts]]...\n\n",
-         play? "" : " outfile");
+         sox_mode == sox_play? "" : " outfile");
   for (i = 0; i < array_length(lines); ++i)
     puts(lines[i]);
   display_supported_formats();
@@ -345,6 +345,116 @@
   sox_format_quit();
 }
 
+static char const * str_time(double duration)
+{
+  static char string[16][50];
+  static int i;
+  int mins = duration / 60;
+  i = (i+1) & 15;
+  sprintf(string[i], "%02i:%05.2f", mins, duration - mins * 60);
+  return string[i];
+}
+
+static void display_file_info(file_t f, sox_bool full)
+{
+  static char const * const no_yes[] = {"no", "yes"};
+  FILE * const output = sox_mode == sox_soxi? stdout : stderr;
+
+  fprintf(output, "\n%s: '%s'",
+    f->ft->mode == 'r'? "Input File     " : "Output File    ", f->ft->filename);
+  if (strcmp(f->ft->filename, "-") == 0 || (f->ft->handler->flags & SOX_FILE_DEVICE))
+    fprintf(output, " (%s)", f->ft->handler->names[0]);
+  fprintf(output, "\n");
+
+  if (f->ft->signal.size)
+    fprintf(output, "Sample Size    : %s (%s)\n",
+        sox_size_bits_str[f->ft->signal.size],
+        sox_sizes_str[f->ft->signal.size]);
+
+  if (f->ft->signal.encoding)
+    fprintf(output, "Sample Encoding: %s\n",
+        sox_encodings_str[f->ft->signal.encoding]);
+
+  fprintf(output,
+    "Channels       : %u\n"
+    "Sample Rate    : %g\n",
+    f->ft->signal.channels,
+    f->ft->signal.rate);
+
+  if (f->ft->length && f->ft->signal.channels && f->ft->signal.rate) {
+    sox_size_t ws = f->ft->length / f->ft->signal.channels;
+    fprintf(output,
+      "Duration       : %s = %u samples %c %g CDDA sectors\n",
+      str_time((double)ws / f->ft->signal.rate),
+      ws, "~="[f->ft->signal.rate == 44100],
+      (double)ws/ f->ft->signal.rate * 44100 / 588);
+  }
+  if (full) {
+    if (f->ft->signal.size > 1)
+      fprintf(output, "Endian Type    : %s\n",
+          f->ft->signal.reverse_bytes != SOX_IS_BIGENDIAN ? "big" : "little");
+    if (f->ft->signal.size)
+      fprintf(output,
+        "Reverse Nibbles: %s\n"
+        "Reverse Bits   : %s\n",
+        no_yes[f->ft->signal.reverse_nibbles],
+        no_yes[f->ft->signal.reverse_bits]);
+  }
+
+  if (f->replay_gain != HUGE_VAL)
+    fprintf(output, "Replay gain    : %+g dB\n" , f->replay_gain);
+  if (f->volume != HUGE_VAL)
+    fprintf(output, "Level adjust   : %g (linear gain)\n" , f->volume);
+
+  if (!(f->ft->handler->flags & SOX_FILE_DEVICE) && f->ft->comments) {
+    if (num_comments(f->ft->comments) > 1) {
+      comments_t p = f->ft->comments;
+      fprintf(output, "Comments       : \n");
+      do fprintf(output, "%s\n", *p);
+      while (*++p);
+    }
+    else fprintf(output, "Comment        : '%s'\n", f->ft->comments[0]);
+  }
+  fprintf(output, "\n");
+}
+
+static void report_file_info(file_t f)
+{
+  if (sox_globals.verbosity > 2)
+    display_file_info(f, sox_true);
+}
+
+static void progress_to_file(file_t f)
+{
+  if (user_skip) {
+    user_skip = sox_false;
+    fprintf(stderr, "\nSkipped (Ctrl-C twice to quit).\n");
+  }
+  read_wide_samples = 0;
+  input_wide_samples = f->ft->length / f->ft->signal.channels;
+  if (show_progress && (sox_globals.verbosity < 3 ||
+                        (combine_method <= sox_concatenate && input_count > 1)))
+    display_file_info(f, sox_false);
+  if (f->volume == HUGE_VAL)
+    f->volume = 1;
+  if (f->replay_gain != HUGE_VAL)
+    f->volume *= pow(10.0, f->replay_gain / 20);
+  f->ft->sox_errno = errno = 0;
+}
+
+static sox_bool since(struct timeval * then, double secs, sox_bool always_reset)
+{
+  sox_bool ret;
+  struct timeval now;
+  time_t d;
+  gettimeofday(&now, NULL);
+  d = now.tv_sec - then->tv_sec;
+  ret = d > ceil(secs) || now.tv_usec - then->tv_usec + d * TIME_FRAC >= secs * TIME_FRAC;
+  if (ret || always_reset)
+    *then = now;
+  return ret;
+}
+
 static file_t new_file(void)
 {
   file_t f = xcalloc(sizeof(*f), 1);
@@ -429,15 +539,16 @@
   return strcaseends(filename, ".m3u") || strcaseends(filename, ".pls");
 }
 
-static void parse_playlist(const file_t f0, char const * const filename)
+static void parse_playlist(int (* callback)(void *, char *), void * p, char const * const listname)
 {
-  sox_bool is_pls = strcaseends(filename, ".pls");
+  sox_bool is_pls = strcaseends(listname, ".pls");
   int comment_char = "#;"[is_pls];
   size_t text_length = 100;
   char * text = xmalloc(text_length + 1);
-  char * dirname = xstrdup(filename);
+  char * dirname = xstrdup(listname);
   char * slash_pos = LAST_SLASH(dirname);
-  FILE * file = xfopen(filename, "r");
+  FILE * file = xfopen(listname, "r");
+  char * filename;
   int c;
 
   if (!slash_pos)
@@ -446,7 +557,7 @@
     *slash_pos = '\0';
 
   if (file == NULL) {
-    sox_fail("Can't open playlist file `%s': %s", filename, strerror(errno));
+    sox_fail("Can't open playlist file `%s': %s", listname, strerror(errno));
     exit(1);
   }
 
@@ -482,32 +593,23 @@
     }
     if (begin != end) {
       char const * id = text + begin;
-      file_t f;
 
-      if (file_count >= MAX_FILES) {
-        sox_fail("Too many filenames; maximum is %d input files and 1 output file", MAX_INPUT_FILES);
-        exit(1);
-      }
-
-      f = new_file();
-      *f = *f0;
       if (!dirname[0] || is_uri(id) || IS_ABSOLUTE(id))
-        f->filename = xstrdup(id);
+        filename = xstrdup(id);
       else {
-        f->filename = xmalloc(strlen(dirname) + strlen(id) + 2); 
-        sprintf(f->filename, "%s/%s", dirname, id); 
+        filename = xmalloc(strlen(dirname) + strlen(id) + 2); 
+        sprintf(filename, "%s/%s", dirname, id); 
       }
-      if (is_playlist(f->filename)) {
-        parse_playlist(f, f->filename);
-        free(f->filename);
-        free(f);
-        continue;
+      if (is_playlist(filename)) {
+        parse_playlist(callback, p, filename);
+        free(filename);
       }
-      files[file_count++] = f;
+      else if (callback(p, filename))
+        break;
     }
   } while (c != EOF);
   if (ferror(file)) {
-    sox_fail("Error reading playlist file `%s': %s", filename, strerror(errno));
+    sox_fail("Error reading playlist file `%s': %s", listname, strerror(errno));
     exit(1);
   }
   fclose(file);
@@ -515,6 +617,68 @@
   free(dirname);
 }
 
+typedef enum {
+  full, rate, channels, samples, duration, bits, encoding, annotation} soxi_t;
+
+static int soxi1(soxi_t * type, char * filename)
+{
+  file_t f = new_file();
+  f->filename = filename;
+  if ((f->ft = sox_open_read(f->filename, NULL, NULL))) {
+    sox_size_t ws = f->ft->length / max(f->ft->signal.channels, 1);
+    switch (*type) {
+      case rate: printf("%g\n", f->ft->signal.rate); break;
+      case channels: printf("%u\n", f->ft->signal.channels); break;
+      case samples: printf("%u\n", ws); break;
+      case duration: printf("%s\n", str_time((double)ws / max(f->ft->signal.rate, 1))); break;
+      case bits: printf("%s\n", sox_size_bits_str[f->ft->signal.size]); break;
+      case encoding: printf("%s\n", sox_encodings_str[f->ft->signal.encoding]); break;
+      case annotation: if (f->ft->comments) {
+        comments_t p = f->ft->comments;
+        do printf("%s\n", *p); while (*++p);
+      }
+      break;
+      case full: display_file_info(f, sox_false); break;
+    }
+    sox_close(f->ft);
+  }
+  free(f);
+  return 0;
+}
+
+static void soxi(int argc, char * const * argv)
+{
+  static char const opts[] = "rcsdbea?";
+  soxi_t type = full;
+  int opt;
+
+  while ((opt = getopt(argc, argv, opts)) > 0)
+    type = 1 + (strchr(opts, opt) - opts);
+  if (type > annotation)
+    printf("Usage: soxi [-r|-c|-s|-d|-b|-e|-a] infile1 ...\n");
+  else for (; optind < argc; ++optind) {
+    if (is_playlist(argv[optind]))
+      parse_playlist(soxi1, &type, argv[optind]);
+    else soxi1(&type, argv[optind]);
+  }
+  exit(0);
+}
+
+static int add_file(file_t f0, char * filename)
+{
+  file_t f;
+
+  if (file_count >= MAX_FILES) {
+    sox_fail("Too many filenames; maximum is %d input files and 1 output file", MAX_INPUT_FILES);
+    exit(1);
+  }
+  f = new_file();
+  *f = *f0;
+  f->filename = filename;
+  files[file_count++] = f;
+  return 0;
+}
+
 static void parse_options_and_filenames(int argc, char **argv)
 {
   file_t f = NULL;
@@ -538,7 +702,7 @@
       if (optind >= argc || sox_find_effect(argv[optind]))
         break;
       if (is_playlist(argv[optind])) {
-        parse_playlist(f, argv[optind++]);
+        parse_playlist(add_file, f, argv[optind++]);
         free(f);
         f = NULL;
         continue;
@@ -549,7 +713,7 @@
     f = NULL;
   }
 
-  if (play) {
+  if (sox_mode == sox_play) {
     if (file_count >= MAX_FILES) {
       sox_fail("Too many filenames; maximum is %d input files and 1 output file", MAX_INPUT_FILES);
       exit(1);
@@ -565,7 +729,7 @@
     free(f); /* No file opts and no filename, so that's okay */
   }
 
-  if (rec) {
+  if (sox_mode == sox_rec) {
     sox_size_t i;
 
     if (file_count >= MAX_FILES) {
@@ -617,21 +781,25 @@
   sox_globals.output_message_handler = output_message;
 
   if (strends(myname, "play")) {
-    play = sox_true;
+    sox_mode = sox_play;
     replay_gain_mode = RG_track;
     combine_method = sox_sequence;
   }
   else if (strends(myname, "rec"))
-    rec = sox_true;
+    sox_mode = sox_rec;
+  else if (strends(myname, "soxi"))
+    sox_mode = sox_soxi;
 
   if (sox_format_init() != SOX_SUCCESS)
-      exit(1);
+    exit(1);
  
+  if (sox_mode == sox_soxi)
+    soxi(argc, argv);
+
   parse_options_and_filenames(argc, argv);
 
   if (sox_globals.verbosity > 2)
     display_SoX_version(stderr);
-
  
   /* Make sure we got at least the required # of input filenames */
   input_count = file_count ? file_count - 1 : 0;
@@ -660,7 +828,7 @@
     if (combine_method == sox_mix && !uservolume)
       f->volume = 1.0 / input_count;
 
-    if (rec && !j) { /* Set the recording sample rate & # of channels: */
+    if (sox_mode == sox_rec && !j) { /* Set the recording sample rate & # of channels: */
       if (input_count > 1) {   /* Get them from the next input file: */
         f->signal.rate = files[1]->ft->signal.rate;
         f->signal.channels = files[1]->ft->signal.channels;
@@ -737,7 +905,7 @@
   if (show_progress) {
     if (user_abort)
       fprintf(stderr, "Aborted.\n");
-    else if (user_skip && !rec)
+    else if (user_skip && sox_mode != sox_rec)
       fprintf(stderr, "Skipped.\n");
     else
       fprintf(stderr, "Done.\n");
@@ -1035,115 +1203,6 @@
       break;
     }
   }
-}
-
-static char const * str_time(double duration)
-{
-  static char string[16][50];
-  static int i;
-  int mins = duration / 60;
-  i = (i+1) & 15;
-  sprintf(string[i], "%02i:%05.2f", mins, duration - mins * 60);
-  return string[i];
-}
-
-static void display_file_info(file_t f, sox_bool full)
-{
-  static char const * const no_yes[] = {"no", "yes"};
-
-  fprintf(stderr, "\n%s: '%s'",
-    f->ft->mode == 'r'? "Input File     " : "Output File    ", f->ft->filename);
-  if (strcmp(f->ft->filename, "-") == 0 || (f->ft->handler->flags & SOX_FILE_DEVICE))
-    fprintf(stderr, " (%s)", f->ft->handler->names[0]);
-  fprintf(stderr, "\n");
-
-  if (f->ft->signal.size)
-    fprintf(stderr, "Sample Size    : %s (%s)\n",
-        sox_size_bits_str[f->ft->signal.size],
-        sox_sizes_str[f->ft->signal.size]);
-
-  if (f->ft->signal.encoding)
-    fprintf(stderr, "Sample Encoding: %s\n",
-        sox_encodings_str[f->ft->signal.encoding]);
-
-  fprintf(stderr,
-    "Channels       : %u\n"
-    "Sample Rate    : %g\n",
-    f->ft->signal.channels,
-    f->ft->signal.rate);
-
-  if (full) {
-    if (f->ft->length && f->ft->signal.channels && f->ft->signal.rate) {
-      sox_size_t ws = f->ft->length / f->ft->signal.channels;
-      fprintf(stderr,
-        "Duration       : %s = %u samples %c %g CDDA sectors\n",
-        str_time((double)ws / f->ft->signal.rate),
-        ws, "~="[f->ft->signal.rate == 44100],
-        (double)ws/ f->ft->signal.rate * 44100 / 588);
-    }
-    if (f->ft->signal.size > 1)
-      fprintf(stderr, "Endian Type    : %s\n",
-          f->ft->signal.reverse_bytes != SOX_IS_BIGENDIAN ? "big" : "little");
-    if (f->ft->signal.size)
-      fprintf(stderr,
-        "Reverse Nibbles: %s\n"
-        "Reverse Bits   : %s\n",
-        no_yes[f->ft->signal.reverse_nibbles],
-        no_yes[f->ft->signal.reverse_bits]);
-  }
-
-  if (f->replay_gain != HUGE_VAL)
-    fprintf(stderr, "Replay gain    : %+g dB\n" , f->replay_gain);
-  if (f->volume != HUGE_VAL)
-    fprintf(stderr, "Level adjust   : %g (linear gain)\n" , f->volume);
-
-  if (!(f->ft->handler->flags & SOX_FILE_DEVICE) && f->ft->comments) {
-    if (num_comments(f->ft->comments) > 1) {
-      comments_t p = f->ft->comments;
-      fprintf(stderr, "Comments       : \n");
-      do fprintf(stderr, "%s\n", *p);
-      while (*++p);
-    }
-    else fprintf(stderr, "Comment        : '%s'\n", f->ft->comments[0]);
-  }
-  fprintf(stderr, "\n");
-}
-
-static void report_file_info(file_t f)
-{
-  if (sox_globals.verbosity > 2)
-    display_file_info(f, sox_true);
-}
-
-static void progress_to_file(file_t f)
-{
-  if (user_skip) {
-    user_skip = sox_false;
-    fprintf(stderr, "Skipped.\n");
-  }
-  read_wide_samples = 0;
-  input_wide_samples = f->ft->length / f->ft->signal.channels;
-  if (show_progress && (sox_globals.verbosity < 3 ||
-                        (combine_method <= sox_concatenate && input_count > 1)))
-    display_file_info(f, sox_false);
-  if (f->volume == HUGE_VAL)
-    f->volume = 1;
-  if (f->replay_gain != HUGE_VAL)
-    f->volume *= pow(10.0, f->replay_gain / 20);
-  f->ft->sox_errno = errno = 0;
-}
-
-static sox_bool since(struct timeval * then, double secs, sox_bool always_reset)
-{
-  sox_bool ret;
-  struct timeval now;
-  time_t d;
-  gettimeofday(&now, NULL);
-  d = now.tv_sec - then->tv_sec;
-  ret = d > ceil(secs) || now.tv_usec - then->tv_usec + d * TIME_FRAC >= secs * TIME_FRAC;
-  if (ret || always_reset)
-    *then = now;
-  return ret;
 }
 
 static void sigint(int s)