1#!/usr/bin/env python
2from string import *
3
4import commands
5import getopt
6import os
7import sys
8
9
10def Usage(mesg):
11    print mesg + os.linesep
12
13    print "Usage: " + os.linesep
14
15    print "Mode 1. Compare output of 'lame1' and 'lame2':"
16    print "./lametest.py  [options] options_file  input.wav lame1 lame2" + os.linesep
17
18    print "Mode 2. Compare output of lame1 with reference solutions:"
19    print "./lametest.py [options] options_file input.wav lame1" + os.linesep
20
21    print "Mode 3. Generate reference solutions using lame1:"
22    print "./lametest.py -m options_file input.wav lame1" + os.linesep
23
24    print "options: "
25    print "   -w   convert mp3's to wav's before comparison"
26
27    sys.exit(0)
28
29
30#
31# compare two files, return # bytes which differ and the
32# number of bytes in larger file
33#
34def fdiff(name1, name2):
35    cmd = "cmp -l " + name1 + " " + name2 + " | wc -l"
36    # XXX either
37    #    use a combination of os.popen + read
38    # or
39    #    write owen cmp+wc function
40    # to replace commands.getoutput
41    out = commands.getoutput(cmd)
42    out = split(out, "\n")
43    out = out[-1]
44    if find(out, "No") == -1:
45        diff = atof(out)
46
47        status = os.access(name1, os.R_OK)
48        if 1 != status:
49            size1 = 0
50        else:
51            size1 = os.path.getsize(name1)
52        size2 = os.path.getsize(name2)
53        diff = diff + abs(size1 - size2)
54        size = max(size1, size2)
55    else:
56        diff = -1
57        size = 0
58    return (diff, size)
59
60#
61# compare two files, return # bytes which differ and the
62# number of bytes in larger file
63#
64
65
66def compare(name1, name2, decode):
67    if decode:
68        print "converting mp3 to wav for comparison..."
69        # XXX shouldn't we use lame1 instead of a hardcoded lame?
70        os.system("lame --quiet --mp3input --decode " + name1)
71        os.system("lame --quiet --mp3input --decode " + name2)
72        name1 = name1 + ".wav"
73        name2 = name2 + ".wav"
74
75    rcode = 0
76    diff, size = fdiff(name1, name2)
77    if diff == 0:
78        print "output identical:  diff=%i  total=%i" % (diff, size)
79        rcode = 1
80    elif diff > 0:
81        print "output different: diff=%i  total=%i  %2.0f%%" % \
82            (diff, size, 100 * float(diff) / size)
83    else:
84        print "Error comparing files:"
85        print "File 1: " + name1
86        print "File 2: " + name2
87
88    return rcode
89
90
91#
92# main program
93#
94try:
95    optlist, args = getopt.getopt(sys.argv[1:], 'wm')
96except getopt.error, val:
97    Usage('ERROR: ' + val)
98
99decode = 0
100lame2 = "none"
101for opt in optlist:
102    if opt[0] == '-w':
103        decode = 1
104    elif opt[0] == '-m':
105        lame2 = "makeref"
106        print os.linesep + "Generating reference output"
107
108
109if len(args) < 3:
110    Usage("Not enough arguments.")
111if len(args) > 4:
112    Usage("Too many arguments.")
113
114if lame2 == "makeref":
115    if len(args) != 3:
116        Usage("Too many arguments for -r/-m mode.")
117else:
118    if len(args) == 3:
119        lame2 = "ref"
120
121# populate variables from args and normalize & expand path
122if len(args) >= 3:
123    options_file = os.path.normpath(os.path.expanduser(args[0]))
124    input_file = os.path.normpath(os.path.expanduser(args[1]))
125    lame1 = os.path.normpath(os.path.expanduser(args[2]))
126if len(args) >= 4:
127    lame2 = os.path.normpath(os.path.expanduser(args[3]))
128
129# check readability of options_file
130status = os.access(options_file, os.R_OK)
131if status != 1:
132    Usage(options_file + " not readable")
133
134# check readability of input_file
135status = os.access(input_file, os.R_OK)
136if status != 1:
137    Usage(input_file + " not readable")
138
139
140# generate searchlist of directories
141path = split(os.environ['PATH'], os.pathsep)
142path.append(os.curdir)
143
144# init indicator vars
145lame1_ok = 0
146lame2_ok = 0
147
148# check for executable lame1
149for x in path:
150    status = os.access(os.path.join(x, lame1), os.X_OK)
151    if status == 1:
152        lame1_ok = 1
153        break
154if lame1_ok != 1:
155    Usage(lame1 + " is not executable")
156
157if not (lame2 == "ref" or lame2 == "makeref"):
158    # check for executable lame2
159    for x in path:
160        status = os.access(os.path.join(x, lame2), os.X_OK)
161        if status == 1:
162            lame2_ok = 1
163            break
164    if lame2_ok != 1:
165        Usage(lame2 + " is not executable")
166
167
168tmp = split(options_file, os.sep)
169tmp = tmp[-1]
170basename = replace(input_file, ".wav", "")
171basename = basename + "." + tmp
172
173
174num_ok = 0
175n = 0
176foptions = open(options_file)
177line = rstrip(foptions.readline())
178while line:
179    n = n + 1
180    name1 = basename + "." + str(n) + ".mp3"
181    name2 = basename + "." + str(n) + "ref.mp3"
182
183    print      # empty line
184
185    if lame2 == 'ref':
186        cmd = "rm -f " + name1
187        os.system(cmd)
188        cmd = lame1 + " --quiet " + line + " " + input_file + " " + name1
189        print "executable:      ", lame1
190        print "options:         ", line
191        print "input:           ", input_file
192        print "reference output:", name2
193        print cmd
194        os.system(cmd)
195        num_ok = num_ok + compare(name1, name2, decode)
196    elif lame2 == 'makeref':
197        cmd = "rm -f " + name2
198        os.system(cmd)
199        print "executable: ", lame1
200        print "options:    ", line
201        print "input:      ", input_file
202        print "output:     ", name2
203        cmd = lame1 + " --quiet " + line + " " + input_file + " " + name2
204        os.system(cmd)
205    else:
206        cmd = "rm -f " + name1
207        os.system(cmd)
208        cmd = "rm -f " + name2
209        os.system(cmd)
210        print "executable:  ", lame1
211        print "executable2: ", lame2
212        print "options:     ", line
213        print "input:       ", input_file
214        cmd1 = lame1 + " --quiet " + line + " " + input_file + " " + name1
215        cmd2 = lame2 + " --quiet " + line + " " + input_file + " " + name2
216        os.system(cmd1)
217        os.system(cmd2)
218        num_ok = num_ok + compare(name1, name2, decode)
219
220    line = rstrip(foptions.readline())
221
222foptions.close()
223
224if lame2 != 'makeref':
225    print os.linesep + "Number of tests which passed: ", num_ok
226    print "Number of tests which failed: ", n - num_ok
227