-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathcrossfade.sh
executable file
·143 lines (121 loc) · 4.86 KB
/
crossfade.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/bin/bash
#
# crossfade.sh
#
# Creates two new files that when played together have a crossfade
# of $1 seconds. This means that $1/2 of the crossfade is in
# the 1st file and $1/2 in the second file. Can be used to
# make audio CD's with a 0 second pregap between songs to
# have one song flow into the next; yet still be able to skip
# around the CD with minimal loss of song.
#
# Filenames are specified as $2 and $3.
#
# $4 is optional and specifies if a fadeout should be performed on
# first file. Can be yes/no/auto.
# $5 is optional and specifies if a fadein should be performed on
# second file. Can be yes/no/auto
#
# Example: $0 10 infile1.wav infile2.wav auto auto
#
# By default, the script attempts to guess if the audio files
# already have a fadein/out on them or if they just have really
# low volumes that won't cause clipping when mixxing. If this
# is not detected then the script will perform a fade in/out to
# prevent clipping.
#
# The user may specify "yes" or "no" to force the fade in/out
# to occur. They can also specify "auto" which is the default.
#
# Crossfaded file $2 is prepended with cfo_ and $3 is prepended
# with cfi_.
#
# Original script from Kester Clegg. Mods by Chris Bagwell to show
# more examples of sox features.
#
SOX=../src/sox
if [ "$3" == "" ]; then
echo "Usage: $0 crossfade_seconds first_file second_file [ fadeout ] [ fadein ]"
echo
echo "If a fadeout or fadein is not desired then specify \"no\" for that option. \"yes\" will force a fade and \"auto\" will try to detect if a fade should occur."
echo
echo "Example: $0 10 infile1.wav infile2.wav auto auto"
exit 1
fi
fade_length=$1
first_file=$2
second_file=$3
fade_first="auto"
if [ "$4" != "" ]; then
fade_first=$4
fi
fade_second="auto"
if [ "$5" != "" ]; then
fade_second=$5
fi
fade_first_opts=
if [ "$fade_first" != "no" ]; then
fade_first_opts="fade t 0 0:0:$fade_length 0:0:$fade_length"
fi
fade_second_opts=
if [ "$fade_second" != "no" ]; then
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 --info -D "$first_file"`
echo "Length is $first_length seconds"
trim_length=`echo "$first_length - $fade_length" | bc`
crossfade_split_length=`echo "scale=2; $fade_length / 2.0" | 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..."
$SOX "$first_file" -e signed-integer -b 16 fadeout1.wav trim $trim_length $fade_first_opts
# When user specifies "auto" try to guess if a fadeout is needed.
# "RMS amplitude" from the stat effect is effectively an average
# value of samples for the whole fade length file. If it seems
# quiet then assume a fadeout has already been done. An RMS value
# of 0.1 was just obtained from trial and error.
if [ "$fade_first" == "auto" ]; then
RMS=`$SOX fadeout1.wav 2>&1 -n stat | grep RMS | grep amplitude | cut -d : -f 2 | cut -f 1`
should_fade=`echo "$RMS > 0.1" | bc`
if [ $should_fade == 0 ]; then
echo "Auto mode decided not to fadeout with RMS of $RMS"
fade_first_opts=""
else
echo "Auto mode will fadeout"
fi
fi
$SOX fadeout1.wav fadeout2.wav $fade_first_opts
# Get the crossfade section from the second file and optionally do the fade in
echo "Obtaining $fade_length seconds of fade in portion from $second_file..."
$SOX "$second_file" -e signed-integer -b 16 fadein1.wav trim 0 $fade_length
# For auto, do similar thing as for fadeout.
if [ "$fade_second" == "auto" ]; then
RMS=`$SOX fadein1.wav 2>&1 -n stat | grep RMS | grep amplitude | cut -d : -f 2 | cut -f 1`
should_fade=`echo "$RMS > 0.1" | bc`
if [ $should_fade == 0 ]; then
echo "Auto mode decided not to fadein with RMS of $RMS"
fade_second_opts=""
else
echo "Auto mode will fadein"
fi
fi
$SOX fadein1.wav fadein2.wav $fade_second_opts
# Mix the crossfade files together at full volume
echo "Crossfading..."
$SOX -m -v 1.0 fadeout2.wav -v 1.0 fadein2.wav crossfade.wav
echo "Spliting crossfade into $crossfade_split_length lengths"
$SOX crossfade.wav crossfade1.wav trim 0 $crossfade_split_length
$SOX crossfade.wav crossfade2.wav trim $crossfade_split_length
echo "Trimming off crossfade sections from original files..."
$SOX "$first_file" -e signed-integer -b 16 song1.wav trim 0 $trim_length
$SOX "$second_file" -e signed-integer -b 16 song2.wav trim $fade_length
echo "Creating crossfade files"
$SOX song1.wav crossfade1.wav "cfo_${first_file}.wav"
$SOX crossfade2.wav song2.wav "cfi_${second_file}.wav"
echo -e "Removing temporary files...\n"
rm fadeout1.wav fadeout2.wav fadein1.wav fadein2.wav crossfade.wav crossfade1.wav crossfade2.wav song1.wav song2.wav
mins=`echo "$trim_length / 60" | bc`
secs=`echo "$trim_length % 60" | bc`
echo "The crossfade occurs at around $mins mins $secs secs in $first_file"