ref: e38ffc2c9716d8764aef7e88ad40d0ebbb572ff2
parent: 083d40f17c381101a75fe3dd80ed27e0b378a09a
author: cbagwell <cbagwell>
date: Sat Feb 19 20:43:31 EST 2011
Support an absolute end position for trim effect instead of only an offset from trim begin.
--- a/ChangeLog
+++ b/ChangeLog
@@ -54,6 +54,8 @@
o Enable LADSPA effects on all platforms without any external
dependencies. Mainly useful for Linux, Windows and OS X which have
binaries readily available. (cbagwell)
+ o Support specifying an absolute end location for trim effect instead
+ only an offset from trim begin location. (Ulrich Klauer)
Other new features:
--- a/sox.1
+++ b/sox.1
@@ -3925,7 +3925,7 @@
.I depth
(default 40).
.TP
-\fBtrim \fIstart\fR [\fIlength\fR]
+\fBtrim \fIstart\fR [\fIlength\fR\^|\^\fB=\fIend\fR]
Trim can trim off unwanted audio from the beginning and end of the
audio. Audio is not sent to the output stream until
the \fIstart\fR location is reached.
@@ -3932,16 +3932,17 @@
.SP
The optional \fIlength\fR parameter gives the length of audio to output
after the \fIstart\fR sample and is thus used to trim off the end of the
-audio. Using a value of 0 for the \fIstart\fR parameter will allow
-trimming off the end only.
+audio. Alternatively, an absolute end location can be given by
+preceding it with an equals sign. Using a value of 0 for the \fIstart\fR
+parameter will allow trimming off the end only.
.SP
-Both options can be specified using either an amount of time or an
+Both parameters can be specified using either an amount of time or an
exact count of samples. The format for specifying lengths in time is
hh:mm:ss.frac. A start value of 1:30\*d5 will not start until 1 minute,
thirty and \(12 seconds into the audio. The format for specifying
sample counts is the number of samples with the letter `s' appended to
-it. A value of 8000s will wait until 8000 samples are read before
-starting to process audio.
+it. A value of 8000s for the \fIstart\fR parameter will wait until
+8000 samples are read before starting to process audio.
.TP
\fBvad \fR[\fIoptions\fR]
Voice Activity Detector. Attempts to trim silence and quiet
--- a/src/trim.c
+++ b/src/trim.c
@@ -12,7 +12,8 @@
typedef struct {
/* options here */
char *start_str;
- char *length_str;
+ char *end_str;
+ sox_bool end_is_absolute;
/* options converted to values */
size_t start;
@@ -28,6 +29,7 @@
*/
static int sox_trim_getopts(sox_effect_t * effp, int argc, char **argv)
{
+ char *end;
priv_t * trim = (priv_t *) effp->priv;
--argc, ++argv;
@@ -36,10 +38,15 @@
*/
switch (argc) {
case 2:
- trim->length_str = lsx_malloc(strlen(argv[1])+1);
- strcpy(trim->length_str,argv[1]);
+ end = argv[1];
+ if (*end == '=') {
+ trim->end_is_absolute = sox_true;
+ end++;
+ } else trim->end_is_absolute = sox_false;
+ trim->end_str = lsx_malloc(strlen(end)+1);
+ strcpy(trim->end_str, end);
/* Do a dummy parse to see if it will fail */
- if (lsx_parsesamples(0., trim->length_str, &trim->length, 't') == NULL)
+ if (lsx_parsesamples(0., trim->end_str, &trim->length, 't') == NULL)
return lsx_usage(effp);
case 1:
trim->start_str = lsx_malloc(strlen(argv[0])+1);
@@ -65,19 +72,29 @@
if (lsx_parsesamples(effp->in_signal.rate, trim->start_str,
&trim->start, 't') == NULL)
return lsx_usage(effp);
- /* Account for # of channels */
- trim->start *= effp->in_signal.channels;
- if (trim->length_str)
+ if (trim->end_str)
{
- if (lsx_parsesamples(effp->in_signal.rate, trim->length_str,
+ if (lsx_parsesamples(effp->in_signal.rate, trim->end_str,
&trim->length, 't') == NULL)
return lsx_usage(effp);
+ if (trim->end_is_absolute) {
+ if (trim->length < trim->start) {
+ lsx_warn("end earlier than start");
+ trim->length = 0;
+ /* with trim->end_str != NULL, this really means zero */
+ } else
+ trim->length -= trim->start;
+ }
}
else
trim->length = 0;
+ /* with trim->end_str == NULL, this means indefinite length */
+ lsx_debug("start at %lus, length %lu", trim->start, trim->length);
+
/* Account for # of channels */
+ trim->start *= effp->in_signal.channels;
trim->length *= effp->in_signal.channels;
trim->index = 0;
@@ -130,7 +147,7 @@
} /* !trimmed */
if (trim->trimmed || start_trim) {
- if (trim->length_str && ((trim->trimmed+done) >= trim->length)) {
+ if (trim->end_str && ((trim->trimmed+done) >= trim->length)) {
/* Since we know the end is in this block, we set done
* to the desired length less the amount already read.
*/
@@ -153,7 +170,7 @@
priv_t * trim = (priv_t *) effp->priv;
free(trim->start_str);
- free(trim->length_str);
+ free(trim->end_str);
return (SOX_SUCCESS);
}
@@ -173,7 +190,7 @@
const sox_effect_handler_t *lsx_trim_effect_fn(void)
{
static sox_effect_handler_t handler = {
- "trim", "start [length]", SOX_EFF_MCHAN | SOX_EFF_LENGTH | SOX_EFF_MODIFY,
+ "trim", "start [length|=end]", SOX_EFF_MCHAN | SOX_EFF_LENGTH | SOX_EFF_MODIFY,
sox_trim_getopts, sox_trim_start, sox_trim_flow,
NULL, NULL, lsx_kill, sizeof(priv_t)
};