test_metaflac.sh 15.4 KB
Newer Older
Josh Coalson's avatar
Josh Coalson committed
1
2
3
#!/bin/sh

#  FLAC - Free Lossless Audio Codec
4
5
#  Copyright (C) 2002-2009  Josh Coalson
#  Copyright (C) 2011-2013  Xiph.Org Foundation
Josh Coalson's avatar
Josh Coalson committed
6
#
Josh Coalson's avatar
Josh Coalson committed
7
#  This file is part the FLAC project.  FLAC is comprised of several
8
#  components distributed under different licenses.  The codec libraries
Josh Coalson's avatar
Josh Coalson committed
9
10
11
12
13
14
#  are distributed under Xiph.Org's BSD-like license (see the file
#  COPYING.Xiph in this distribution).  All other programs, libraries, and
#  plugins are distributed under the GPL (see COPYING.GPL).  The documentation
#  is distributed under the Gnu FDL (see COPYING.FDL).  Each file in the
#  FLAC distribution contains at the top the terms under which it may be
#  distributed.
Josh Coalson's avatar
Josh Coalson committed
15
#
Josh Coalson's avatar
Josh Coalson committed
16
17
18
19
#  Since this particular file is relevant to all components of FLAC,
#  it may be distributed under the Xiph.Org license, which is the least
#  restrictive of those mentioned above.  See the file COPYING.Xiph in this
#  distribution.
Josh Coalson's avatar
Josh Coalson committed
20

21
22
23
24
25
26
die ()
{
	echo $* 1>&2
	exit 1
}

27
if [ x = x"$1" ] ; then
28
29
30
31
32
	BUILD=debug
else
	BUILD="$1"
fi

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# change to 'false' to show all flac/metaflac output (useful for debugging)
if true ; then
	SILENT='--silent'
	TOTALLY_SILENT='--totally-silent'
else
	SILENT=''
	TOTALLY_SILENT=''
fi

LD_LIBRARY_PATH=`pwd`/../src/libFLAC/.libs:$LD_LIBRARY_PATH
LD_LIBRARY_PATH=`pwd`/../src/share/grabbag/.libs:$LD_LIBRARY_PATH
LD_LIBRARY_PATH=`pwd`/../src/share/getopt/.libs:$LD_LIBRARY_PATH
LD_LIBRARY_PATH=`pwd`/../src/share/replaygain_analysis/.libs:$LD_LIBRARY_PATH
LD_LIBRARY_PATH=`pwd`/../src/share/replaygain_synthesis/.libs:$LD_LIBRARY_PATH
LD_LIBRARY_PATH=`pwd`/../src/share/utf8/.libs:$LD_LIBRARY_PATH
48
LD_LIBRARY_PATH=`pwd`/../objs/$BUILD/lib:$LD_LIBRARY_PATH
Josh Coalson's avatar
Josh Coalson committed
49
export LD_LIBRARY_PATH
50
export MALLOC_CHECK_=3
51
export MALLOC_PERTURB_=$(($(date +%s) % 255 + 1))
52
53
PATH=`pwd`/../src/flac:$PATH
PATH=`pwd`/../src/metaflac:$PATH
54
PATH=`pwd`/../objs/$BUILD/bin:$PATH
Josh Coalson's avatar
Josh Coalson committed
55

56
57
58
59
60
if echo a | (grep -E '(a|b)') >/dev/null 2>&1
	then EGREP='grep -E'
	else EGREP='egrep'
fi

61
62
testdir="metaflac-test-files"
flacfile="metaflac.flac"
Josh Coalson's avatar
Josh Coalson committed
63

64
65
flac --help 1>/dev/null 2>/dev/null || die "ERROR can't find flac executable"
metaflac --help 1>/dev/null 2>/dev/null || die "ERROR can't find metaflac executable"
66

Josh Coalson's avatar
Josh Coalson committed
67
68
run_flac ()
{
69
	if [ x"$FLAC__TEST_WITH_VALGRIND" = xyes ] ; then
70
		echo "valgrind --leak-check=yes --show-reachable=yes --num-callers=50 flac $*" >>test_metaflac.valgrind.log
71
		valgrind --leak-check=yes --show-reachable=yes --num-callers=50 --log-fd=4 flac --no-error-on-compression-fail $* 4>>test_metaflac.valgrind.log
Josh Coalson's avatar
Josh Coalson committed
72
	else
73
		flac --no-error-on-compression-fail $*
Josh Coalson's avatar
Josh Coalson committed
74
75
76
77
78
	fi
}

run_metaflac ()
{
79
	if [ x"$FLAC__TEST_WITH_VALGRIND" = xyes ] ; then
80
81
		echo "valgrind --leak-check=yes --show-reachable=yes --num-callers=50 metaflac $*" >>test_metaflac.valgrind.log
		valgrind --leak-check=yes --show-reachable=yes --num-callers=50 --log-fd=4 metaflac $* 4>>test_metaflac.valgrind.log
Josh Coalson's avatar
Josh Coalson committed
82
83
84
85
	else
		metaflac $*
	fi
}
Josh Coalson's avatar
Josh Coalson committed
86

87
88
89
90
91
92
run_metaflac_silent ()
{
	if [ -z "$SILENT" ] ; then
		run_metaflac $*
	else
		if [ x"$FLAC__TEST_WITH_VALGRIND" = xyes ] ; then
93
94
			echo "valgrind --leak-check=yes --show-reachable=yes --num-callers=50 metaflac $*" >>test_metaflac.valgrind.log
			valgrind --leak-check=yes --show-reachable=yes --num-callers=50 --log-fd=4 metaflac $* 2>/dev/null 4>>test_metaflac.valgrind.log
95
96
97
98
99
100
101
102
103
104
105
		else
			metaflac $* 2>/dev/null
		fi
	fi
}

check_flac ()
{
	run_flac --silent --test $flacfile || die "ERROR in $flacfile" 1>&2
}

106
echo "Generating stream..."
107
108
bytes=80000
if dd if=/dev/zero ibs=1 count=$bytes | flac --force --verify -0 --input-size=$bytes --output-name=$flacfile --force-raw-format --endian=big --sign=signed --channels=1 --bps=8 --sample-rate=8000 - ; then
109
110
	chmod +w $flacfile
else
111
	die "ERROR during generation"
Josh Coalson's avatar
Josh Coalson committed
112
113
fi

114
115
116
117
118
check_flac

echo

filter ()
Josh Coalson's avatar
Josh Coalson committed
119
{
120
121
122
	# minor danger, changing vendor strings will change the length of the
	# VORBIS_COMMENT block, but if we add "^  length: " to the patterns,
	# we lose info about PADDING size that we need
123
124
125
126
	# grep pattern 1: remove vendor string
	# grep pattern 2: remove minimum/maximum frame and block size from STREAMINFO
	# grep pattern 3: remove hexdump data from PICTURE metadata blocks
	# sed pattern 1: remove stream offset values from SEEKTABLE points
127
	$EGREP -v '^  vendor string: |^  m..imum .....size: |^    0000[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]: ' | sed -e 's/, stream_offset.*//'
Josh Coalson's avatar
Josh Coalson committed
128
}
129
metaflac_test ()
Josh Coalson's avatar
Josh Coalson committed
130
{
131
132
133
134
135
136
	case="$1"
	desc="$2"
	args="$3"
	expect="$testdir/$case-expect.meta"
	echo -n "test $case: $desc... "
	run_metaflac $args $flacfile | filter > $testdir/out.meta || die "ERROR running metaflac"
137
	diff -w $expect $testdir/out.meta > /dev/null 2>&1 || die "ERROR: metadata does not match expected $expect"
138
	echo OK
Josh Coalson's avatar
Josh Coalson committed
139
140
}

141
metaflac_test case00 "--list" "--list"
142

143
144
145
146
147
148
149
150
151
152
metaflac_test case01 "STREAMINFO --show-* shortcuts" "
	--show-md5sum
	--show-min-blocksize
	--show-max-blocksize
	--show-min-framesize
	--show-max-framesize
	--show-sample-rate
	--show-channels
	--show-bps
	--show-total-samples"
153

154
run_metaflac --preserve-modtime --add-padding=12345 $flacfile
155
check_flac
156
metaflac_test case02 "--add-padding" "--list"
157

Josh Coalson's avatar
Josh Coalson committed
158
# some flavors of /bin/sh (e.g. Darwin's) won't even handle quoted spaces, so we underscore:
159
run_metaflac --set-tag="ARTIST=The_artist_formerly_known_as_the_artist..." $flacfile
160
check_flac
161
metaflac_test case03 "--set-tag=ARTIST" "--list"
162

163
run_metaflac --set-tag="ARTIST=Chuck_Woolery" $flacfile
164
check_flac
165
metaflac_test case04 "--set-tag=ARTIST" "--list"
166

167
run_metaflac --set-tag="ARTIST=Vern" $flacfile
168
check_flac
169
metaflac_test case05 "--set-tag=ARTIST" "--list"
170

171
run_metaflac --set-tag="TITLE=He_who_smelt_it_dealt_it" $flacfile
172
check_flac
173
metaflac_test case06 "--set-tag=TITLE" "--list"
174

175
metaflac_test case07 "--show-vendor-tag --show-tag=ARTIST" "--show-vendor-tag --show-tag=ARTIST"
Josh Coalson's avatar
Josh Coalson committed
176

177
run_metaflac --remove-first-tag=ARTIST $flacfile
178
check_flac
179
metaflac_test case08 "--remove-first-tag=ARTIST" "--list"
180

181
run_metaflac --remove-tag=ARTIST $flacfile
182
check_flac
183
metaflac_test case09 "--remove-tag=ARTIST" "--list"
184

185
186
187
188
189
190
metaflac_test case10 "--list --block-type=VORBIS_COMMENT" "--list --block-type=VORBIS_COMMENT"
metaflac_test case11 "--list --block-number=0" "--list --block-number=0"
metaflac_test case12 "--list --block-number=1,2,999" "--list --block-number=1,2,999"
metaflac_test case13 "--list --block-type=VORBIS_COMMENT,PADDING" "--list --block-type=VORBIS_COMMENT,PADDING"
metaflac_test case14 "--list --except-block-type=SEEKTABLE,VORBIS_COMMENT" "--list --except-block-type=SEEKTABLE,VORBIS_COMMENT"
metaflac_test case15 "--list --except-block-type=STREAMINFO" "--list --except-block-type=STREAMINFO"
191

192
run_metaflac --add-padding=4321 $flacfile $flacfile
193
check_flac
194
metaflac_test case16 "--add-padding=4321 * 2" "--list"
195

196
run_metaflac --merge-padding $flacfile
197
check_flac
198
metaflac_test case17 "--merge-padding" "--list"
199

200
run_metaflac --add-padding=0 $flacfile
201
check_flac
202
metaflac_test case18 "--add-padding=0" "--list"
203

204
run_metaflac --sort-padding $flacfile
205
check_flac
206
metaflac_test case19 "--sort-padding" "--list"
207

208
run_metaflac --add-padding=0 $flacfile
209
check_flac
210
metaflac_test case20 "--add-padding=0" "--list"
211

212
run_metaflac --remove-all-tags $flacfile
213
check_flac
214
metaflac_test case21 "--remove-all-tags" "--list"
215

216
run_metaflac --remove --block-number=1,99 --dont-use-padding $flacfile
217
check_flac
218
metaflac_test case22 "--remove --block-number=1,99 --dont-use-padding" "--list"
219

220
run_metaflac --remove --block-number=99 --dont-use-padding $flacfile
221
check_flac
222
metaflac_test case23 "--remove --block-number=99 --dont-use-padding" "--list"
223

224
run_metaflac --remove --block-type=PADDING $flacfile
225
check_flac
226
metaflac_test case24 "--remove --block-type=PADDING" "--list"
227

228
run_metaflac --remove --block-type=PADDING --dont-use-padding $flacfile
229
check_flac
230
metaflac_test case25 "--remove --block-type=PADDING --dont-use-padding" "--list"
231

232
run_metaflac --add-padding=0 $flacfile $flacfile
233
check_flac
234
metaflac_test case26 "--add-padding=0 * 2" "--list"
235

236
run_metaflac --remove --except-block-type=PADDING $flacfile
237
check_flac
238
metaflac_test case27 "--remove --except-block-type=PADDING" "--list"
239

240
run_metaflac --remove-all $flacfile
241
check_flac
242
metaflac_test case28 "--remove-all" "--list"
243

244
run_metaflac --remove-all --dont-use-padding $flacfile
245
check_flac
246
metaflac_test case29 "--remove-all --dont-use-padding" "--list"
247

248
run_metaflac --remove-all --dont-use-padding $flacfile
249
check_flac
250
metaflac_test case30 "--remove-all --dont-use-padding" "--list"
251

252
run_metaflac --set-tag="f=0123456789abcdefghij" $flacfile
Josh Coalson's avatar
Josh Coalson committed
253
check_flac
254
metaflac_test case31 "--set-tag=..." "--list"
255

256
run_metaflac --remove-all-tags --set-tag="f=0123456789abcdefghi" $flacfile
Josh Coalson's avatar
Josh Coalson committed
257
check_flac
258
metaflac_test case32 "--remove-all-tags --set-tag=..." "--list"
Josh Coalson's avatar
Josh Coalson committed
259

260
run_metaflac --remove-all-tags --set-tag="f=0123456789abcde" $flacfile
Josh Coalson's avatar
Josh Coalson committed
261
check_flac
262
metaflac_test case33 "--remove-all-tags --set-tag=..." "--list"
Josh Coalson's avatar
Josh Coalson committed
263

264
run_metaflac --remove-all-tags --set-tag="f=0" $flacfile
Josh Coalson's avatar
Josh Coalson committed
265
check_flac
266
metaflac_test case34 "--remove-all-tags --set-tag=..." "--list"
Josh Coalson's avatar
Josh Coalson committed
267

268
run_metaflac --remove-all-tags --set-tag="f=0123456789" $flacfile
Josh Coalson's avatar
Josh Coalson committed
269
check_flac
270
metaflac_test case35 "--remove-all-tags --set-tag=..." "--list"
Josh Coalson's avatar
Josh Coalson committed
271

272
run_metaflac --remove-all-tags --set-tag="f=0123456789abcdefghi" $flacfile
Josh Coalson's avatar
Josh Coalson committed
273
check_flac
274
metaflac_test case36 "--remove-all-tags --set-tag=..." "--list"
Josh Coalson's avatar
Josh Coalson committed
275

276
run_metaflac --remove-all-tags --set-tag="f=0123456789" $flacfile
Josh Coalson's avatar
Josh Coalson committed
277
check_flac
278
metaflac_test case37 "--remove-all-tags --set-tag=..." "--list"
Josh Coalson's avatar
Josh Coalson committed
279

280
run_metaflac --remove-all-tags --set-tag="f=0123456789abcdefghij" $flacfile
Josh Coalson's avatar
Josh Coalson committed
281
check_flac
282
metaflac_test case38 "--remove-all-tags --set-tag=..." "--list"
Josh Coalson's avatar
Josh Coalson committed
283

284
echo "TITLE=Tittle" | run_metaflac --import-tags-from=- $flacfile
Josh Coalson's avatar
Josh Coalson committed
285
check_flac
286
metaflac_test case39 "--import-tags-from=-" "--list"
Josh Coalson's avatar
Josh Coalson committed
287
288
289
290
291

cat > vc.txt << EOF
artist=Fartist
artist=artits
EOF
292
run_metaflac --import-tags-from=vc.txt $flacfile
Josh Coalson's avatar
Josh Coalson committed
293
check_flac
294
metaflac_test case40 "--import-tags-from=[FILE]" "--list"
Josh Coalson's avatar
Josh Coalson committed
295
296
297

rm vc.txt

298
299
300
301
302
303
304
305
run_metaflac --add-replay-gain $flacfile
check_flac
metaflac_test case41 "--add-replay-gain" "--list"

run_metaflac --remove-replay-gain $flacfile
check_flac
metaflac_test case42 "--remove-replay-gain" "--list"

306
# CUESHEET blocks
307
308
309
cs_in=cuesheets/good.000.cue
cs_out=metaflac.cue
cs_out2=metaflac2.cue
310
run_metaflac --import-cuesheet-from="$cs_in" $flacfile
311
check_flac
312
313
314
metaflac_test case43 "--import-cuesheet-from" "--list"
run_metaflac --export-cuesheet-to=$cs_out $flacfile
run_metaflac --remove --block-type=CUESHEET $flacfile
315
check_flac
316
317
metaflac_test case44 "--remove --block-type=CUESHEET" "--list"
run_metaflac --import-cuesheet-from=$cs_out $flacfile
318
check_flac
319
320
metaflac_test case45 "--import-cuesheet-from" "--list"
run_metaflac --export-cuesheet-to=$cs_out2 $flacfile
321
echo "comparing cuesheets:"
322
diff $cs_out $cs_out2 || die "ERROR, cuesheets should be identical"
323
324
325
326
echo identical

rm -f $cs_out $cs_out2

327
328
329
330
331
332
333
# PICTURE blocks
ncase=46
for f in \
	0.gif \
	1.gif \
	2.gif \
; do
334
	run_metaflac --import-picture-from="|image/gif|$f||pictures/$f" $flacfile
335
	check_flac
336
	metaflac_test "case$ncase" "--import-picture-from" "--list"
337
338
339
340
341
342
	ncase=`expr $ncase + 1`
done
for f in \
	0.jpg \
	4.jpg \
; do
343
	run_metaflac --import-picture-from="4|image/jpeg|$f||pictures/$f" $flacfile
344
	check_flac
345
	metaflac_test "case$ncase" "--import-picture-from" "--list"
346
347
348
349
350
351
352
353
354
355
356
357
358
	ncase=`expr $ncase + 1`
done
for f in \
	0.png \
	1.png \
	2.png \
	3.png \
	4.png \
	5.png \
	6.png \
	7.png \
	8.png \
; do
359
	run_metaflac --import-picture-from="5|image/png|$f||pictures/$f" $flacfile
360
	check_flac
361
	metaflac_test "case$ncase" "--import-picture-from" "--list"
362
363
	ncase=`expr $ncase + 1`
done
Josh Coalson's avatar
Josh Coalson committed
364
[ $ncase = 60 ] || die "expected case# to be 60"
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379

fn=export-picture-check
echo -n "Testing --export-picture-to... "
run_metaflac --export-picture-to=$fn $flacfile
check_flac
cmp $fn pictures/0.gif || die "ERROR, exported picture file and original differ"
echo OK
rm -f $fn
echo -n "Testing --block-number --export-picture-to... "
run_metaflac --block-number=9 --export-picture-to=$fn $flacfile
check_flac
cmp $fn pictures/0.png || die "ERROR, exported picture file and original differ"
echo OK
rm -f $fn

380
381
382
run_metaflac --remove --block-type=PICTURE $flacfile
check_flac
metaflac_test case60 "--remove --block-type=PICTURE" "--list"
383
run_metaflac --import-picture-from="1|image/png|standard_icon|32x32x24|pictures/0.png" $flacfile
384
check_flac
385
386
metaflac_test case61 "--import-picture-from" "--list"
run_metaflac --import-picture-from="2|image/png|icon|64x64x24|pictures/1.png" $flacfile
387
check_flac
388
metaflac_test case62 "--import-picture-from" "--list"
389
390

# UNKNOWN blocks
391
392
echo -n "Testing FLAC file with unknown metadata... "
cp -p metaflac.flac.in $flacfile
393
394
# remove the VORBIS_COMMENT block so vendor string changes don't interfere with the comparison:
run_metaflac --remove --block-type=VORBIS_COMMENT --dont-use-padding $flacfile
395
396
397
cmp $flacfile metaflac.flac.ok || die "ERROR, $flacfile and metaflac.flac.ok differ"
echo OK

398
399
400
401
402
# Replay gain tests - Test the rates which have specific filter table entries
# and verify that harmonics can be processed correctly.

tonegenerator ()
{
403
	# When using GAWK, use --lint=posix to identify non-POSIX awk usages.
404
405
406
407
408
409
410
411
    awk -- '
    BEGIN {
            samplerate = '$1';

            tone = 1000;
            duration = 1;
            bitspersample = 24;

412
413
414
415
416
            samplemidpoint = 1;
			for (sps = 0 ; sps < bitspersample - 1 ; sps++) {
				samplemidpoint *= 2;
			}

417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
            samplerange = samplemidpoint - 1;

            pi = 4 * atan2(1,1);

            for (ix = 0; ix < duration * samplerate; ++ix) {
                    sample = sin(2 * pi * tone * ix / samplerate);
                    sample *= samplerange;
                    sample += samplemidpoint;
                    sample = int(sample);
                    for (bx = 0; bx < bitspersample/8; ++bx) {
                            byte[bx] = sample % 256;
                            sample /= 256;
                    }
                    while (bx--) {
                            printf("%c", byte[bx]);
                    }
            }

    }' /dev/null |
436
    flac --no-error-on-compression-fail --silent \
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
        --endian=big --channels=1 --bps=24 --sample-rate=$1 --sign=unsigned -
}

REPLAYGAIN_FREQ=
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ  8000/-12.73"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 11025/-12.93"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 11025/-12.93"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 12000/-12.98"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 16000/-13.27"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 18900/-13.41"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 22050/-13.77"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 24000/-13.82"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 28000/-14.06"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 32000/-14.08"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 36000/-14.12"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 37800/-14.18"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 44100/-14.17"
REPLAYGAIN_FREQ="$REPLAYGAIN_FREQ 48000/-14.16:1:2:4"

456
457
set -e

458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
for ACTION in $REPLAYGAIN_FREQ ; do
  if [ -n "${ACTION##*:*}" ] ; then
    HARMONICS=1
  else
    HARMONICS="${ACTION#*:}"
  fi
  FREQ="${ACTION%%/*}"
  GAIN="${ACTION#*/}"
  GAIN="${GAIN%%:*}"
  while [ -n "$HARMONICS" ] ; do
    MULTIPLE="${HARMONICS%%:*}"
    if [ x"$MULTIPLE" = x"$HARMONICS" ] ; then
      HARMONICS=
    else
      HARMONICS="${HARMONICS#*:}"
    fi
    RATE=$(($MULTIPLE * FREQ))
    [ $MULTIPLE -eq 1 -o -n "${REPLAYGAIN_FREQ##* $RATE/*}" ] || break
    echo -n "Testing FLAC replaygain $RATE ($FREQ x $MULTIPLE) ... "
    tonegenerator $RATE > $flacfile
    run_metaflac --add-replay-gain $flacfile
    run_metaflac --list $flacfile | grep REPLAYGAIN.*GAIN= |
    while read -r REPLAYGAIN ; do
      MEASUREDGAIN="${REPLAYGAIN##*=}"
      MEASUREDGAIN="${MEASUREDGAIN%% *}"
      if [ x"$MEASUREDGAIN" != x"$GAIN" ] ; then
        die "ERROR, Expected $GAIN db instead of $REPLAYGAIN"
      fi
    done
    echo OK
  done
done


492
rm -f $testdir/out.flac $testdir/out.meta
493

Josh Coalson's avatar
Josh Coalson committed
494
exit 0