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