ref: c290ba369a4af8ba4ed7df2d4ed401fd1a02c9ca
parent: 5259fd4d5897b15b669523d01f7f2883d0c256e1
author: Ulrich Klauer <ulrich@chirlu.de>
date: Wed Jan 25 20:44:44 EST 2012
trim: only warn about positions beyond end of file If the user specifies positions after the input audio length, warn but don't fail; they might intend "at most ..." semantics. It's especially important for cases like the man page example sox infile.wav outfile.wav trim 0 30 : newfile : restart that would otherwise fail if the input length is not exactly a multiple of 30 seconds.
--- a/src/trim.c
+++ b/src/trim.c
@@ -92,11 +92,12 @@
case a_start: res = s; break;
case a_latest: res = last_seen + s; break;
case a_end:
- if (s > in_length) {
+ if (s <= in_length)
+ res = in_length - s;
+ else {
lsx_fail("Position %u is before start of audio.", i+1);
return SOX_EOF;
}
- res = in_length - s;
break;
}
last_seen = p->pos[i].sample = res;
@@ -112,16 +113,11 @@
}
last_seen = p->pos[i].sample;
}
- if (p->num_pos && in_length != SOX_UNKNOWN_LEN &&
- p->pos[0].sample > in_length) {
- lsx_fail("Start position after end of audio.");
- return SOX_EOF;
- }
- if (p->num_pos && in_length != SOX_UNKNOWN_LEN &&
- p->pos[p->num_pos-1].sample > in_length) {
- lsx_fail("End position after end of audio.");
- return SOX_EOF;
- }
+ if (p->num_pos && in_length != SOX_UNKNOWN_LEN)
+ if (p->pos[0].sample > in_length ||
+ p->pos[p->num_pos-1].sample > in_length)
+ lsx_warn("%s position after expected end of audio.",
+ p->pos[0].sample > in_length? "Start" : "End");
if (p->num_pos == 1 && !p->pos[0].sample)
return SOX_EFF_NULL;
@@ -134,10 +130,10 @@
effp->out_signal.length = 0;
for (i = 0; i+1 < p->num_pos ; i += 2)
effp->out_signal.length +=
- p->pos[i+1].sample - p->pos[i].sample;
+ min(p->pos[i+1].sample, in_length) - min(p->pos[i].sample, in_length);
if (open_end)
effp->out_signal.length +=
- in_length - p->pos[p->num_pos-1].sample;
+ in_length - min(p->pos[p->num_pos-1].sample, in_length);
effp->out_signal.length *= effp->in_signal.channels;
}