Changed ogg decoder to oggdec.
mp3togo/helpers.py
1 # helpers.py: functions to interpret coder program output.
2 # mp3togo Portable Music Manager
3 #
4 # Copyright 2005: Simeon Veldstra <reallifesim@gmail.com>
5 #
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc.
19 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #
21 # ***********************************************************
22 # The code to parse output from external programs is based on
23 # the jack CD ripping program by Arne Zellentin.
24 #
25 # 'jack' is responsible for my full hard disks
26 # and has inspired me to produce this program.
27 # Thanks for everything Arne.
28
29
30 import os
31 import shutil
32
33 #import mp3togo.conf as conf
34
35
36 class frames:
37 def __init__(self):
38 self.frames = 0
39 self.tframes = 0
40
41 def parse_ogg123(buf):
42 s = buf.split('\r')
43 def sumtime(t):
44 sum = float(t.split(':')[0]) * 60
45 sum += float(t.split(':')[1])
46 return sum
47 for l in s:
48 if l.startswith('Time') and l.endswith('% '):
49 line = l.split(' ')
50 return sumtime(line[1])/sumtime(line[4]) * 100.0
51 return 0
52
53 def parse_mpg321(buf, f=frames()):
54 s = buf.split('\r')
55 if len(s) >= 2:
56 s = s[-2]
57 else:
58 s = s[-1]
59 if not f.tframes:
60 y0 = s.find('[')
61 y1 = s.find(']')
62 if y0 != -1 and y1 != -1:
63 try:
64 f.tframes = float(s[y0+1:y1])
65 except ValueError:
66 pass
67 if f.tframes:
68 try:
69 r = float(s.split()[1])
70 except ValueError:
71 r = f.tframes
72 if r < f.frames:
73 f.tframes = f.frames = 0
74 return 0
75 f.frames = r
76 return f.frames/f.tframes * 100.0
77 return 0
78
79 def parse_oggdec(buf):
80 s = buf.split('\r')
81 if len(s) == 2 and len(s[1]) == 9:
82 return float(s[1][2:7])
83 else:
84 return 0.0
85
86 def parse_oggenc(buf):
87 # From "jack"
88 s = buf.split('\r')
89 if len(s) >= 2:
90 s = s[-2]
91 if len(s) == 1:
92 s = s[0]
93 y0 = s.find("[")
94 y1 = s.find("%]")
95 if y0 != -1 and y1 != -1:
96 percent = float(s[y0 + 1:y1])
97 else:
98 percent = 0
99 return percent
100
101 def parse_lame(buf):
102 # originaly from "jack"
103 s = buf.split('\r')
104 if len(s) >= 2:
105 s = s[-1] or s[-2]
106 if len(s) == 1: s=s[0]
107 if s.find("%") >= 0: # status reporting starts here
108 y = s.split("/")
109 y1 = y[1].split("(")[0]
110 percent = float(y[0]) / float(y1) * 100.0
111 elif s.find("Frame:") >= 0: # older versions, like 3.13
112 y = s.split("/")
113 y0 = y[0].split("[")[-1]
114 y1 = y[1].split("]")[0]
115 percent = float(y0) / float(y1) * 100.0
116 else:
117 percent = 0
118 return percent
119
120 def parse_flac_enc(buf):
121 # From "jack"
122 s = buf.split('\r')
123 if len (s) >= 2: s = s[-2]
124 if len (s) == 1: s = s[0]
125 y0 = s.find(": ")
126 y1 = s.find("%")
127 if y0 != -1 and y1 != -1:
128 return float(s[y0 + 1:y1])
129 else:
130 return 0
131
132 def parse_flac_dec(buf):
133 # I wrote this one myself
134 buf = buf.split('\r')
135 buf = buf[-1]
136 buf = buf.replace('%', '')
137 try:
138 return int(buf.split()[1])
139 except IndexError:
140 return 0
141
142 #### wav file "encoder/decoder"
143 #def recode_wav(input, output, args=None):
144 # """Factory returns function to copy wav file
145 #
146 # Returned function takes no args and copies
147 # input to output. Throws OSError on error."""
148 # return lambda: shutil.copyfile(input, output)
149
150 def parse_m4a_dec(buf):
151 n = buf.find('% decoding')
152 # if n==1 then we are at single digit progress (i.e. 5%) and
153 # at the beginning of the buffer
154 if n == 1:
155 s = buf[0]
156 # else we are somewhere deeper in the buffer...check if we are at
157 # single or double digit progress by looking two characters back
158 elif buf[n-2] == '\n':
159 s = buf[n-1:n]
160 else:
161 s = buf[n-2:n]
162 return int(s)
163
164
165 ## Command line escape sequences:
166 #
167 # escape: for:
168 # ---------------------
169 # %% %
170 # %o output filename
171 # %i input filename
172 # %a args
173
174 helpers = {
175 'oggenc' : {'parser': parse_oggenc,
176 'cmd': 'oggenc %a -o %o %i',
177 'type': 'ogg',
178 'factor': 16.5,
179 'action': 'encode'},
180 'lame' : {'parser': parse_lame,
181 'cmd': 'lame --nohist %a %i %o',
182 'type': 'mp3',
183 'factor': 16.5,
184 'action': 'encode'},
185 # 'flac_enc':{'parser': parse_flac_enc,
186 # 'cmd': 'flac ???????',
187 # 'type': 'flac',
188 # 'action': 'encode'},
189 'wav_enc': {'parser': None,
190 #'cmd': recode_wav,
191 'cmd': 'cp %i %c',
192 'type': 'wav',
193 'factor': 1,
194 'action': 'encode'},
195 # 'ogg123' : {'parser': parse_ogg123,
196 # 'cmd': 'ogg123 -d wav -f %o %i',
197 # 'type': 'ogg',
198 # 'factor': 16.5,
199 # 'action': 'decode'},
200 'ogg123' : {'parser': parse_oggdec,
201 'cmd': 'oggdec -o %o %i',
202 'type': 'ogg',
203 'factor': 16.5,
204 'action': 'decode'},
205 'mpg321' : {'parser': parse_mpg321,
206 'cmd': 'mpg321 -v -w %o %i',
207 'type': 'mp3',
208 'factor': 16.5,
209 'action': 'decode'},
210 'flac_dec':{'parser': parse_flac_dec,
211 'cmd': 'flac --decode -F -o %o %i',
212 'type': 'flac',
213 'factor': 2.8,
214 'action': 'decode'},
215 'm4a_dec': {'parser': parse_m4a_dec,
216 'cmd': 'faad -o %o %i',
217 'type': 'm4a',
218 'factor': 16.5,
219 'action': 'decode'},
220 'wav_dec': {'parser': None,
221 #'cmd': recode_wav,
222 'cmd': 'cp %i %o',
223 'type': 'wav',
224 'factor': 1,
225 'action': 'decode'},
226 }
227
228