3 # SoX script: testtones.sh (c) 2009 robs@users.sourceforge.net
4 # Based on an original idea by Carsten Borchardt
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by the
8 # Free Software Foundation; either version 2 of the License, or (at your
9 # option) any later version.
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14 # Public License for more details.
16 # You should have received a copy of the GNU General Public License along
17 # with this program; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 # Usage: testtones.sh [RATE [AUDIO_LENGTH]]
24 # This script generate files containing audio tones of various
25 # frequencies and power levels that can be used to test an audio
26 # system's reproduction quality and response. By default, the
27 # generated files are suitable for writing to a test CD (using a
28 # programme such as k3b).
30 # The audio files are created in the current directory and a list of
31 # the files generated is also created. A description of each
32 # generated file is sent to the console as the script executes.
34 # RATE (default 44100) is the sample-rate at which to generate the
35 # test tones. Use 48000 to test a PC/work-station or DAT system.
37 # AUDIO_LENGTH (default 36) sets the length in seconds of (most of)
40 # Other parameters can be changed in the Configuration section below.
46 sox
="../src/sox" # Where is sox? E.g. sox, /usr/local/bin/sox
47 type=wav
# File type, e.g. flac, cdda
48 rate
=44100 # Default sample rate
49 #chans2="-c 2" # Uncomment for all files to have 2 channels
50 part_octave
=6 # 5 for harmonic split, 6 for true half octave
51 tone_length
=36 # In seconds; not used for sweeps
52 fade_time
=.05 # Fade in/out time (for smooth start and end of tone)
53 gain
="gain -1" # Headroom for playpack chain
54 #NDD=-D # Uncomment to disable TPDF default dither
55 vol_dither
="-f ge" # Type of dither to be used for volume tests
56 plot
=yes # Uncomment to enable PNG plots
62 [ -n "$plot" ] && [ -n "$name" ] && $sox -D "$name" -n \
63 spectrogram
-h -w kaiser
-o "`basename "$name" $type`png"
68 next_file
() # Generate incrementing file name; update variables
70 plot
# the previous file
72 file_count
=$
(($file_count + 1))
73 name
=`printf "%02i-%s.$type" $file_count "$1" | tr / "~"`
77 length
=$tone_length; [ -n "$2" ] && length
=$2
78 total_length
=$
(($total_length + $length))
80 output
="-b 16 $chans2 --comment="" $name"
81 fade
="fade h $fade_time $length $fade_time"
88 [ -n "$1" ] && rate
="$1"
89 [ -n "$2" ] && tone_length
="$2"
91 log
="`basename "$0"`.log"
92 : > $log # Initialise log file
94 total_length
=0 # In seconds
98 input
="$sox $NDD -r $rate -n"
100 echo "Creating test audio files with sample-rate = $rate"
104 echo; echo "Silence:"
107 $input -D $output trim
0 $length
111 echo; echo "Noise colours:"
113 next_file white-noise
114 $input $output synth
$length whitenoise
$fade $gain
116 $input $output synth
$length pinknoise
$fade $gain
117 next_file brown-noise
118 $input $output synth
$length brownnoise
$fade $gain
122 echo; echo "Single, fixed frequency pure tones, half octave steps:"
124 note
=-60 # 5 octaves below middle A = 13.75Hz
125 while [ $note -le 67 ]; do # 5 and a bit octaves above middle A ~= 20kHz
126 if [ -x /usr
/bin
/bc ]; then
127 freq
=`echo "scale = 9; 440 * e($note / 12 * l(2))" | bc -l`
128 next_file
`printf "%.1f" $freq`Hz
132 $input $output synth
-j 0 sine
%$note $fade $gain
133 note
=$
(($note + $part_octave))
134 part_octave
=$
((12 - $part_octave))
139 echo; echo "Single, fixed frequency pure tones, decade/sub-decade steps:"
141 for freq
in 20 50 100 200 500 1k
2k
5k
10k
20k
; do
142 next_file
"${freq}hz"
143 $input $output synth sine
$freq $fade $gain
148 echo; echo "Single, fixed frequency pure tones, CD frequency sub-harmonics:"
150 for freq
in 5512.5 11025 16537.5 22050; do
151 next_file
"cd-${freq}hz"
152 $input $output synth
$length sine
$freq 0 25 $fade $gain
157 echo; echo "Sweep frequency @ 1 semitone/s, with a mark @ each octave of \`A':"
161 for freq
in %-60/%67 %67/%-60; do
162 next_file
${freq}_sweep
127
163 $input $output synth sine
%30 \
164 synth sine amod
8.333333333333333333 0 $phase1 \
165 synth squa amod
0.08333333333333333333 0 $phase2 1 gain
-9 \
166 synth
$length sine mix
$freq gain
-h 3 $gain
167 phase1
=41.66666666666666667
168 phase2
=42.66666666666666667
173 echo; echo "Dual, fixed frequency pure tones:"
176 $input $output synth
$length sine
9k synth sine mix
10k
$fade $gain
177 next_file
440hz
+445hz
178 $input $output synth
$length sine
440 synth sine mix
445 $fade $gain
182 echo; echo "Single, fixed frequency harmonic tones:"
184 for freq
in 100 1k
5k
; do
185 for shape
in square saw
; do
186 next_file
${freq}hz_
$shape
187 $input $output synth
$length $shape $freq $fade gain
-3
193 echo; echo "Single, fixed frequency pure tones, 12dB attenuation steps:"
195 for freq
in $freqs; do
196 for att
in 12 24 36 48 60 72 84 96 108; do
197 next_file
${freq}hz_
${att}dB_att
198 $input $output synth
$length sine
$freq gain
-h -$att $fade dither
$vol_dither
204 echo; echo "Sweep volume @ 1dB/s, -108->0->-108dB, with a mark (-40dB) every 12dB:"
206 for freq
in $freqs; do
207 next_file
${freq}hz_108dB-sweep
216
208 $input $output synth
$length sin
$freq sin
%30 \
209 synth squ amod
0 100 sine amod
8.333333333333333333 0 75 \
210 synth exp amod
0.00462962962962962963 0 0 50 54 \
211 squ amod
0.08333333333333333333 0 1 1 \
212 remix
1v
.99,2v
.01 dither
$vol_dither
217 echo; echo "1kHz tone offset with 1Hz:"
219 next_file offset_10
%_square
220 $input $output synth
$length square
1 sine
1000 remix
1v0.05
,2v0.95 gain
-h 0 $fade $gain
221 next_file offset_50
%_sine
222 $input $output synth
$length sine
1 synth sine mix
1000 $fade $gain
226 echo; echo "Silence on one channel, full volume on the other:"
228 for freq
in $freqs; do
229 next_file
${freq}hz_left-chan
230 $input $output synth
$length sine
$freq remix
1 0 gain
-h 0 $fade $gain
231 next_file
${freq}hz_right-chan
232 $input $output synth
$length sine
$freq remix
0 1 gain
-h 0 $fade $gain
237 echo; echo "Phase difference (24, 90, 180 degrees) between channels:"
239 for freq
in $freqs; do
240 for phase
in 6.667 25 50; do
241 next_file
${freq}hz_phase-
$phase
242 $input $output synth
$length sine
$freq sine
$freq 0 $phase $fade $gain
248 echo; echo "Plucked scale:"
252 for f
in pluck pluck_dist
; do
257 while [ $note -lt 17 ]; do
258 $input -t s32
- synth
.4 pluck
%$note $options >> tmp.s32
261 $input -t s32
- synth
1.2 pluck
%$note $options >> tmp.s32
263 while [ $note -gt -29 ]; do
264 $input -t s32
- synth
.4 pluck
%$note $options >> tmp.s32
267 $input -t s32
- synth pluck
%$note $options fade t
0 4 3.6 >> tmp.s32
269 $sox -r $rate -c 1 tmp.s32
$output $overdrive remix
1 1 reverb
30
272 options
="0 0 60 75 0"
273 overdrive
="overdrive gain -10"
279 minutes
=$
(($total_length / 60))
280 seconds
=$
(($total_length - $minutes * 60))
281 echo; echo "Sample-rate = $rate; # files created = $file_count; total audio length = `printf "%i
:%02i
" $minutes $seconds`"