ref: c4a08032074cdf097cfb13683efb4cfad74b96c6
parent: d3a8f86ef1aaf2861afb292ba546be24afdf9cfa
author: cbagwell <cbagwell>
date: Thu Sep 16 19:08:58 EDT 2004
Bugfixes to trim effect. Allows crossfade script to work without pops.
--- a/Changelog
+++ b/Changelog
@@ -41,6 +41,10 @@
to not result in the original file.
o Fixed a possible overflow in lots of effects were MIN
value was treated as -MAX instead of -MAX-1.
+ o Modifed sox so its OK for effects to not process any
+ input or output bytes as long as they return ST_EOF.
+ o Bugfix to trim effect were bytes were left off the end
+ of the file when output length was specified.
sox-12.17.5
-----------
--- a/scripts/crossfade_cat.sh
+++ b/scripts/crossfade_cat.sh
@@ -45,21 +45,21 @@
fade_first_opts=
if [ "$fade_first" == "yes" ]; then
- fade_first_opts="fade h 0 0:0:$fade_length"
+ fade_first_opts="fade t 0 0:0:$fade_length"
fi
fade_second_opts=
if [ "$fade_second" == "yes" ]; then
- fade_second_opts="fade h 0:0:$fade_length"
+ fade_second_opts="fade t 0:0:$fade_length"
fi
echo "crossfade and concatenate files"
echo
echo "Finding length of $first_file..."
-first_length=`$SOX "$first_file" 2>&1 -e stat | grep Length | cut -d : -f 2 | cut -d . -f 1 | cut -f 1`
-echo "Length is $first_length"
+first_length=`$SOX "$first_file" 2>&1 -e stat | grep Length | cut -d : -f 2 | cut -f 1`
+echo "Length is $first_length seconds"
-trim_length=`expr $first_length - $fade_length`
+trim_length=`echo "$first_length - $fade_length" | bc`
# Get crossfade section from first file and optionally do the fade out
echo "Obtaining $fade_length seconds of fade out portion from $first_file..."
@@ -79,7 +79,7 @@
echo -e "Removing temporary files...\n"
rm fadeout.wav fadein.wav crossfade.wav song1.wav song2.wav
-mins=`expr $trim_length / 60`
-secs=`expr $trim_length % 60`
+mins=`echo "$trim_length / 60" | bc`
+secs=`echo "$trim_length % 60" | bc`
echo "The crossfade in mix.wav occurs at around $mins mins $secs secs"
--- a/src/fade.c
+++ b/src/fade.c
@@ -230,8 +230,9 @@
t_ibuf = (fade->samplesdone < 0 ? 0 : *ibuf);
if ((fade->samplesdone >= fade->in_start) &&
- (fade->out_stop == 0 || fade->samplesdone < fade->out_stop))
+ (!fade->do_out || fade->samplesdone < fade->out_stop))
{ /* something to generate output */
+
if (fade->samplesdone < fade->in_stop)
{ /* fade-in phase, increase gain */
*obuf = t_ibuf *
@@ -239,14 +240,11 @@
fade->in_stop - fade->in_start,
fade->in_fadetype);
} /* endif fade-in */
-
- if (fade->samplesdone >= fade->in_stop &&
- (!fade->do_out || fade->samplesdone < fade->out_start))
+ else if (!fade->do_out || fade->samplesdone < fade->out_start)
{ /* steady gain phase */
*obuf = t_ibuf;
} /* endif steady phase */
-
- if (fade->do_out && fade->samplesdone >= fade->out_start)
+ else
{ /* fade-out phase, decrease gain */
*obuf = t_ibuf *
fade_gain(fade->out_stop - fade->samplesdone,
@@ -261,6 +259,9 @@
t_output = 0;
} /* endif something to output */
+ /* samplesdone < 0 means we are inventing samples right now
+ * and so not consuming (happens when in_start < 0).
+ */
if (fade->samplesdone >= 0 )
{ /* Something to input */
*isamp += 1;
--- a/src/sox.c
+++ b/src/sox.c
@@ -988,10 +988,10 @@
efftab[e].olen = odonel + odoner;
done = idonel + idoner + odonel + odoner;
}
- if (done == 0)
- st_fail("Effect took & gave no samples!");
if (effstatus == ST_EOF)
return -1;
+ if (done == 0)
+ st_fail("Effect took & gave no samples!");
return 1;
}
--- a/src/trim.c
+++ b/src/trim.c
@@ -45,41 +45,41 @@
* time related strings.
*/
switch (n) {
- case 2:
- trim->length_str = malloc(strlen(argv[1])+1);
- if (!trim->length_str)
- {
- st_fail("Could not allocate memory");
- return(ST_EOF);
- }
- strcpy(trim->length_str,argv[1]);
- /* Do a dummy parse to see if it will fail */
- if (st_parsesamples(0, trim->length_str,
- &trim->length, 't') != ST_SUCCESS)
- {
- st_fail(TRIM_USAGE);
- return(ST_EOF);
- }
- case 1:
- trim->start_str = malloc(strlen(argv[0])+1);
- if (!trim->start_str)
- {
- st_fail("Could not allocate memory");
- return(ST_EOF);
- }
- strcpy(trim->start_str,argv[0]);
- /* Do a dummy parse to see if it will fail */
- if (st_parsesamples(0, trim->start_str,
- &trim->start, 't') != ST_SUCCESS)
- {
- st_fail(TRIM_USAGE);
- return(ST_EOF);
- }
- break;
- default:
- st_fail(TRIM_USAGE);
- return ST_EOF;
- break;
+ case 2:
+ trim->length_str = malloc(strlen(argv[1])+1);
+ if (!trim->length_str)
+ {
+ st_fail("Could not allocate memory");
+ return(ST_EOF);
+ }
+ strcpy(trim->length_str,argv[1]);
+ /* Do a dummy parse to see if it will fail */
+ if (st_parsesamples(0, trim->length_str,
+ &trim->length, 't') != ST_SUCCESS)
+ {
+ st_fail(TRIM_USAGE);
+ return(ST_EOF);
+ }
+ case 1:
+ trim->start_str = malloc(strlen(argv[0])+1);
+ if (!trim->start_str)
+ {
+ st_fail("Could not allocate memory");
+ return(ST_EOF);
+ }
+ strcpy(trim->start_str,argv[0]);
+ /* Do a dummy parse to see if it will fail */
+ if (st_parsesamples(0, trim->start_str,
+ &trim->start, 't') != ST_SUCCESS)
+ {
+ st_fail(TRIM_USAGE);
+ return(ST_EOF);
+ }
+ break;
+ default:
+ st_fail(TRIM_USAGE);
+ return ST_EOF;
+ break;
}
return (ST_SUCCESS);
@@ -93,24 +93,25 @@
trim_t trim = (trim_t) effp->priv;
if (st_parsesamples(effp->ininfo.rate, trim->start_str,
- &trim->start, 't') != ST_SUCCESS)
+ &trim->start, 't') != ST_SUCCESS)
{
- st_fail(TRIM_USAGE);
- return(ST_EOF);
+ st_fail(TRIM_USAGE);
+ return(ST_EOF);
}
/* Account for # of channels */
trim->start *= effp->ininfo.channels;
+
if (trim->length_str)
{
- if (st_parsesamples(effp->ininfo.rate, trim->length_str,
- &trim->length, 't') != ST_SUCCESS)
- {
- st_fail(TRIM_USAGE);
- return(ST_EOF);
- }
+ if (st_parsesamples(effp->ininfo.rate, trim->length_str,
+ &trim->length, 't') != ST_SUCCESS)
+ {
+ st_fail(TRIM_USAGE);
+ return(ST_EOF);
+ }
}
else
- trim->length = 0;
+ trim->length = 0;
/* Account for # of channels */
trim->length *= effp->ininfo.channels;
@@ -144,35 +145,35 @@
* If so then we can skip trimming from the front side.
*/
if (!trim->trimmed) {
- if ((trim->index+done) <= trim->start) {
- /* If we haven't read more then "start" samples, return that
- * we've read all this buffer without outputing anything
- */
- *osamp = 0;
- *isamp = done;
- trim->index += done;
- return (ST_SUCCESS);
- } else {
- start_trim = 1;
- /* We've read at least "start" samples. Now find
- * out where our target data begins and subtract that
- * from the total to be copied this round.
- */
- offset = trim->start - trim->index;
- done -= offset;
- }
+ if ((trim->index+done) <= trim->start) {
+ /* If we haven't read more then "start" samples, return that
+ * we've read all this buffer without outputing anything
+ */
+ *osamp = 0;
+ *isamp = done;
+ trim->index += done;
+ return (ST_SUCCESS);
+ } else {
+ start_trim = 1;
+ /* We've read at least "start" samples. Now find
+ * out where our target data begins and subtract that
+ * from the total to be copied this round.
+ */
+ offset = trim->start - trim->index;
+ done -= offset;
+ }
} /* !trimmed */
if (trim->trimmed || start_trim) {
- if (trim->length && ((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.
- */
- done = trim->length - trim->trimmed;
- finished = 1;
- }
+ if (trim->length && ((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.
+ */
+ done = trim->length - trim->trimmed;
+ finished = 1;
+ }
- trim->trimmed += done;
+ trim->trimmed += done;
}
memcpy(obuf, ibuf+offset, done * sizeof(st_sample_t));
@@ -181,10 +182,13 @@
*isamp = offset + done;
trim->index += done;
- if (finished)
- return (ST_EOF);
+ /* return ST_EOF when nothing consumed and we detect
+ * we are finished.
+ */
+ if (finished && !done)
+ return (ST_EOF);
else
- return (ST_SUCCESS);
+ return (ST_SUCCESS);
}
/*
@@ -196,9 +200,9 @@
trim_t trim = (trim_t) effp->priv;
if (trim->start_str)
- free(trim->start_str);
+ free(trim->start_str);
if (trim->length_str)
- free(trim->length_str);
+ free(trim->length_str);
return (ST_SUCCESS);
}