ref: 374f9408a0468eb756887e0e7aef5955836f628f
parent: a65561ef6694031d264354a50835ff556c16c9bc
author: robs <robs>
date: Fri Jul 4 13:15:05 EDT 2008
attempt to fix play with multiple file rates etc.
--- a/src/sox.c
+++ b/src/sox.c
@@ -72,6 +72,8 @@
static enum {sox_sequence, sox_concatenate, sox_mix, sox_merge, sox_multiply}
combine_method = sox_concatenate;
+#define is_serial(m) ((m) <= sox_concatenate)
+#define is_parallel(m) (!is_serial(m))
static sox_bool interactive = sox_false;
static sox_bool uservolume = sox_false;
typedef enum {RG_off, RG_track, RG_album} rg_mode;
@@ -130,8 +132,8 @@
/* Flowing */
-static sox_signalinfo_t combiner_signal, ofile_signal;
-static sox_encodinginfo_t combiner_encoding, ofile_encoding;
+static sox_signalinfo_t combiner_signal, ofile_signal_options;
+static sox_encodinginfo_t combiner_encoding, ofile_encoding_options;
static sox_size_t mixing_clips = 0;
static size_t current_input = 0;
static unsigned long input_wide_samples = 0;
@@ -338,7 +340,7 @@
strerror(ft->sox_errno) : sox_strerror[ft->sox_errno - SOX_EHDR]);
}
-static void progress_to_file(file_t * f)
+static void progress_to_next_input_file(file_t * f)
{
if (user_skip) {
user_skip = sox_false;
@@ -347,7 +349,7 @@
read_wide_samples = 0;
input_wide_samples = f->ft->signal.length / f->ft->signal.channels;
if (show_progress && (sox_globals.verbosity < 3 ||
- (combine_method <= sox_concatenate && input_count > 1)))
+ (is_serial(combine_method) && input_count > 1)))
display_file_info(f->ft, f, sox_false);
if (f->volume == HUGE_VAL)
f->volume = 1;
@@ -356,6 +358,8 @@
f->ft->sox_errno = errno = 0;
}
+/* Read up to max `wide' samples. A wide sample contains one sample per channel
+ * from the input audio. */
static sox_size_t sox_read_wide(sox_format_t * ft, sox_sample_t * buf, sox_size_t max)
{
sox_size_t len = max / combiner_signal.channels;
@@ -376,6 +380,8 @@
}
}
+/* The input combiner: contains one sample buffer per input file, but only
+ * needed if is_parallel(combine_method) */
typedef struct {
sox_sample_t *ibuf[MAX_INPUT_FILES];
} input_combiner_t;
@@ -385,13 +391,13 @@
input_combiner_t * z = (input_combiner_t *) effp->priv;
sox_size_t ws, i;
- if (combine_method <= sox_concatenate)
- progress_to_file(files[current_input]);
+ if (is_serial(combine_method))
+ progress_to_next_input_file(files[current_input]);
else {
ws = 0;
for (i = 0; i < input_count; i++) {
z->ibuf[i] = lsx_malloc(sox_globals.bufsiz * sizeof(sox_sample_t));
- progress_to_file(files[i]);
+ progress_to_next_input_file(files[i]);
ws = max(ws, input_wide_samples);
}
input_wide_samples = ws; /* Output length is that of longest input file. */
@@ -413,7 +419,7 @@
sox_size_t ilen[MAX_INPUT_FILES];
sox_size_t olen = 0;
- if (combine_method <= sox_concatenate) while (sox_true) {
+ if (is_serial(combine_method)) while (sox_true) {
if (!user_skip)
olen = sox_read_wide(files[current_input]->ft, obuf, *osamp);
if (olen == 0) { /* If EOF, go to the next input file. */
@@ -420,7 +426,7 @@
if (++current_input < input_count) {
if (combine_method == sox_sequence && !can_segue(current_input))
break;
- progress_to_file(files[current_input]);
+ progress_to_next_input_file(files[current_input]);
continue;
}
}
@@ -471,7 +477,7 @@
input_combiner_t * z = (input_combiner_t *) effp->priv;
sox_size_t i;
- if (combine_method > sox_concatenate)
+ if (is_parallel(combine_method))
/* Free input buffers now that they are not used */
for (i = 0; i < input_count; i++)
free(z->ibuf[i]);
@@ -783,7 +789,7 @@
{
static struct timeval then;
if (input_count > 1 && show_progress && s == SIGINT &&
- combine_method <= sox_concatenate && since(&then, 1.0, sox_true))
+ is_serial(combine_method) && since(&then, 1.0, sox_true))
user_skip = sox_true;
else user_abort = sox_true;
}
@@ -839,7 +845,7 @@
combine_method == sox_merge? total_channels : max_channels;
}
- ofile->signal = ofile_signal;
+ ofile->signal = ofile_signal_options;
if (ofile->signal.rate == 0)
ofile->signal.rate = combiner_signal.rate;
if (ofile->signal.channels == 0) {
@@ -853,7 +859,12 @@
combiner_signal.rate *= sox_effects_globals.speed;
- ofile->encoding = ofile_encoding; {
+ ofile->encoding = ofile_encoding_options;
+
+ /* Get unspecified output file encoding attributes from the input file
+ * and set the output file to the resultant encoding if this is
+ * supported by the output file type. */
+ {
sox_encodinginfo_t t = ofile->encoding;
if (!t.encoding)
t.encoding = combiner_encoding.encoding;
@@ -871,6 +882,8 @@
ofile->signal.length = (sox_size_t)(olen * ofile->signal.channels * ofile->signal.rate / combiner_signal.rate + .5);
open_output_file();
+ ofile_effects_chain.length = 0; /* FIXME: needs proper cleanup of effects
+ chain memory. `kill' auto effects? */
ofile_effects_chain.global_info = sox_effects_globals;
ofile_effects_chain.in_enc = &combiner_encoding;
ofile_effects_chain.out_enc = &ofile->ft->encoding;
@@ -884,7 +897,6 @@
flowstatus = sox_flow_effects(&ofile_effects_chain, update_status);
- sox_delete_effects(&ofile_effects_chain);
return flowstatus;
}
@@ -1656,7 +1668,7 @@
/* Make sure we got at least the required # of input filenames */
input_count = file_count ? file_count - 1 : 0;
- if (input_count < (combine_method <= sox_concatenate ? 1 : 2))
+ if (input_count < (is_serial(combine_method) ? 1 : 2))
usage("Not enough input filenames specified");
/* Check for misplaced input/output-specific options */
@@ -1738,13 +1750,14 @@
srand((unsigned)t);
}
- ofile_signal = ofile->signal;
- ofile_encoding = ofile->encoding;
+ ofile_signal_options = ofile->signal;
+ ofile_encoding_options = ofile->encoding;
if (combine_method == sox_sequence) do {
if (ofile->ft)
sox_close(ofile->ft);
} while (process() != SOX_EOF && !user_abort && current_input < input_count);
else process();
+ sox_delete_effects(&ofile_effects_chain);
for (i = 0; i < file_count; ++i)
if (files[i]->ft->clips != 0)