1use strict;
2
3use File::Spec::Functions;
4use FindBin ();
5use Test::More tests => 58;
6
7use Audio::Scan;
8
9# TODO: LPCM_low profile test
10
11# WAV file with ID3 tags
12{
13    local $ENV{AUDIO_SCAN_NO_ARTWORK} = 1;
14
15    my $s = Audio::Scan->scan( _f('id3.wav'), { md5_size => 4096 } );
16
17    my $info = $s->{info};
18    my $tags = $s->{tags};
19
20    is( $info->{audio_offset}, 44, 'Audio offset ok' );
21    is( $info->{audio_size}, 1904, 'Audio size ok' );
22    is( $info->{audio_md5}, 'f69093529247ffd1dfaa5b7c66a19377', 'Audio MD5 ok' );
23    is( $info->{bitrate}, 1411200, 'Bitrate ok' );
24    is( $info->{bits_per_sample}, 16, 'Bits/sample ok' );
25    is( $info->{block_align}, 4, 'Block align ok' );
26    is( $info->{channels}, 2, 'Channels ok' );
27    is( $info->{file_size}, 4240, 'File size ok' );
28    is( $info->{format}, 1, 'Format ok' );
29    is( $info->{samplerate}, 44100, 'Sample rate ok' );
30    is( $info->{song_length_ms}, 10, 'Song length ok' );
31    is( $info->{id3_version}, 'ID3v2.3.0', 'ID3 version ok' );
32    is( $info->{dlna_profile}, 'LPCM', 'DLNA profile ok' );
33
34    is( ref $tags->{COMM}, 'ARRAY', 'COMM ok' );
35    is( $tags->{TALB}, 'WAV Album', 'TALB ok' );
36    is( $tags->{TCON}, 'Alternative', 'TCON ok' );
37    is( $tags->{TDRC}, 2009, 'TDRC ok' );
38    is( $tags->{TIT2}, 'WAV Title', 'TIT2 ok' );
39    is( $tags->{TPE1}, 'WAV Artist', 'TPE1 ok' );
40    is( $tags->{TPOS}, 1, 'TPOS ok' );
41    is( $tags->{TRCK}, 5, 'TRCK ok' );
42
43    # Bug 17392, make sure artwork offset is correct when ID3 tag is not at the front of the file
44    is( ref $tags->{APIC}, 'ARRAY', 'APIC ok' );
45    is( $tags->{APIC}->[0], 'image/jpg', 'APIC type ok' );
46    is( $tags->{APIC}->[3], 2103, 'APIC length ok' );
47    is( $tags->{APIC}->[4], 2137, 'APIC offset ok' );
48}
49
50# 32-bit WAV with PEAK info
51{
52    my $s = Audio::Scan->scan( _f('wav32.wav') );
53
54    my $info = $s->{info};
55
56    is( $info->{audio_offset}, 88, '32-bit WAV audio offset ok' );
57    is( $info->{audio_size}, 3808, '32-bit WAV audio size ok' );
58    is( $info->{bitrate}, 2822400, '32-bit WAV bitrate ok' );
59    is( $info->{bits_per_sample}, 32, '32-bit WAV bits/sample ok' );
60    is( $info->{block_align}, 8, '32-bit WAV block align ok' );
61    is( ref $info->{peak}, 'ARRAY', '32-bit WAV PEAK ok' );
62    is( $info->{peak}->[0]->{position}, 284, '32-bit WAV Peak 1 ok' );
63    is( $info->{peak}->[1]->{position}, 47, '32-bit WAV Peak 2 ok' );
64    like( $info->{peak}->[0]->{value}, qr/^0.477/, '32-bit WAV Peak 1 value ok' );
65    like( $info->{peak}->[1]->{value}, qr/^0.476/, '32-bit WAV Peak 2 value ok' );
66    ok( !exists $info->{dlna_profile}, '32-bit WAV no DLNA profile ok' );
67}
68
69# MP3 in WAV
70{
71    my $s = Audio::Scan->scan( _f('8kmp38.wav') );
72
73    my $info = $s->{info};
74
75    is( $info->{bitrate}, 8000, 'MP3 WAV bitrate ok' );
76    is( $info->{format}, 85, 'MP3 WAV format ok' );
77    is( $info->{samplerate}, 8000, 'MP3 WAV samplerate ok' );
78    is( $info->{song_length_ms}, 13811, 'MP3 WAV length ok' );
79}
80
81# Wav with INFO tags and wrong chunk size in header
82{
83    my $s = Audio::Scan->scan( _f('wav32-info-badchunk.wav') );
84
85    my $tags = $s->{tags};
86
87    is( $tags->{IART}, 'They Might Be Giants', 'IART ok' );
88    is( $tags->{ICRD}, 2005, 'ICRD ok' );
89    is( $tags->{IGNR}, 'Soundtrack', 'IGNR ok' );
90    is( $tags->{INAM}, 'Here Come The ABCs', 'INAM ok' );
91    is( $tags->{IPRD}, 'Here Come The Abcs With Tmbg - Original Songs About The Alphabet', 'IPRD ok' );
92}
93
94# Bug 14946, WAV file with INFO tags with trailing nulls
95{
96    my $s = Audio::Scan->scan( _f('wav32-info-nulls.wav') );
97
98    my $tags = $s->{tags};
99
100    is( $tags->{IART}, 'Archies, The', 'INFO nulls IART ok' );
101    is( $tags->{ICMT}, 'Gift From Uncle Roddy', 'INFO nulls ICMT ok' );
102    is( $tags->{ICRD}, 1997, 'INFO nulls ICRD ok' );
103    is( $tags->{IGNR}, 'Pop', 'INFO nulls IGNR ok' );
104    is( $tags->{INAM}, 'Tester Bang Shang A Lang', 'INFO nulls INAM ok' );
105    is( $tags->{IPRD}, 'When I Was Young', 'INFO nulls IPRD ok' );
106}
107
108# Bug 14462, WAV file with 18-byte fmt chunk
109{
110    my $s = Audio::Scan->scan( _f('bug14462-wav-fmt.wav') );
111
112    my $info = $s->{info};
113
114    is( $info->{audio_offset}, 58, '18-byte fmt audio offset ok' );
115    is( $info->{song_length_ms}, 7418, '18-byte fmt duration ok' );
116}
117
118# Bug 14462, WAV file with bad data size
119{
120    my $s = Audio::Scan->scan( _f('bug14462-wav-bad-data-size.wav') );
121
122    my $info = $s->{info};
123
124    is( $info->{audio_offset}, 44, 'bad data size audio offset ok' );
125    is( $info->{song_length_ms}, 2977, 'bad data size duration ok' );
126}
127
128# GH #2, bad duration calculated for files where the 'fact' chunk num_samples value is used
129{
130    my $s = Audio::Scan->scan( _f('gh2-wav32-bad-duration.wav') );
131
132    my $info = $s->{info};
133
134    is( $info->{bits_per_sample}, 32, 'GH#2, 32/384 bps ok' );
135    is( $info->{samplerate}, 384000, 'GH#2, 32/384 samplerate ok' );
136    is( $info->{song_length_ms}, 20000, 'GH#2, song_length_ms ok for 32/384 file with a high number of samples' );
137}
138
139sub _f {
140    return catfile( $FindBin::Bin, 'wav', shift );
141}
142