summaryrefslogtreecommitdiff
path: root/jack_helpers.py
diff options
context:
space:
mode:
authorMartin Michlmayr <tbm@cyrius.com>2006-02-05 20:24:07 +0100
committerMartin Michlmayr <tbm@cyrius.com>2006-02-05 20:24:07 +0100
commit97d87e1fa0808cf747bf0a4fe3b39d1cbdb5efc8 (patch)
treec817c2371ea765b6fd6f9e47f4985209dd1937dd /jack_helpers.py
Import jack_3.1.1+cvs20050801.orig.tar.gz
[dgit import orig jack_3.1.1+cvs20050801.orig.tar.gz]
Diffstat (limited to 'jack_helpers.py')
-rw-r--r--jack_helpers.py541
1 files changed, 541 insertions, 0 deletions
diff --git a/jack_helpers.py b/jack_helpers.py
new file mode 100644
index 0000000..e0ba931
--- /dev/null
+++ b/jack_helpers.py
@@ -0,0 +1,541 @@
+# -*- coding: iso-8859-15 -*-
+### jack_helpers: helper applications for
+### jack - extract audio from a CD and encode it using 3rd party software
+### Copyright (C) 1999-2004 Arne Zellentin <zarne@users.sf.net>
+
+### This program is free software; you can redistribute it and/or modify
+### it under the terms of the GNU General Public License as published by
+### the Free Software Foundation; either version 2 of the License, or
+### (at your option) any later version.
+
+### This program is distributed in the hope that it will be useful,
+### but WITHOUT ANY WARRANTY; without even the implied warranty of
+### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+### GNU General Public License for more details.
+
+### You should have received a copy of the GNU General Public License
+### along with this program; if not, write to the Free Software
+### Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+import string
+import re
+
+import jack_plugins
+
+from jack_globals import *
+
+
+helpers = {
+ 'builtin': {
+ 'type': "dummy",
+ 'status_blocksize': 160
+ },
+
+ 'oggenc': { # based on a patch kindly provided by Bryan Larsen.
+ 'type': "encoder",
+ 'target': "ogg",
+ 'can_tag': 1,
+ 'vbr-cmd': "oggenc -o %o -t %t -a %a -N %n -l %l -G %g -d %y -q %q %i",
+ 'cmd': "oggenc -o %o -t %t -a %a -N %n -l %l -G %g -d %y -b %r %i",
+ 'tags': {
+ 'ogg': {
+ 'track': "-t %s",
+ 'artist': "-a %s",
+ 'number': "-N %s",
+ 'album': "-l %s",
+ 'genre': "-G %s",
+ 'date': "-d %s",
+ },
+ },
+ 'status_blocksize': 64,
+ 'bitrate_factor': 1,
+ 'status_start': "%",
+ 'percent_fkt': r"""
+s = string.split(i['buf'], '\r')
+if len(s) >= 2:
+ s = s[-2]
+if len(s) == 1:
+ s = s[0]
+y0 = string.find(s, "[")
+y1 = string.find(s, "%]")
+if y0 != -1 and y1 != -1:
+ try:
+ percent = float(s[y0 + 1:y1])
+ except ValueError:
+ percent = 0
+else:
+ percent = 0
+""",
+ },
+
+ 'mp3enc': {
+ 'type': "encoder",
+ 'target': "mp3",
+ 'cmd': "mp3enc -v -qual 9 -br %r -if %i -of %o",
+ 'otf-cmd': "mp3enc -v -qual 9 -br %r -sti -be -of %o",
+ 'status_blocksize': 99,
+ 'bitrate_factor': 1000,
+ 'status_start': "%",
+ 'percent_fkt': r"""
+s = string.split(i['buf'], '\r')
+if len(s) >= 4:
+ s = s[-2]
+ if string.find(s, "%") >= 0:
+ y = string.split(s, " ", 3)
+ percent = float(y[0]) / (i['track'][LEN] * CDDA_BLOCKSIZE / 2) * 100.0
+ else:
+ percent = 0
+""",
+ },
+
+ 'l3enc': {
+ 'type': "encoder",
+ 'target': "mp3",
+ 'cmd': "l3enc -hq -br %r %i %o",
+ 'status_blocksize': 99,
+ 'bitrate_factor': 1000,
+ 'status_start': "%",
+ 'percent_fkt': r"""
+s = string.split(i['buf'], '\r')
+if len(s) >= 2: s = s[-2]
+if len(s) == 1: s = s[0]
+if string.find(s, "%") >= 0:
+ y = string.split(s, " / ")
+ y0 = string.split(y[0])[-1]
+ y1 = string.split(y[1])[0]
+ percent=float(y0) / float(y1) * 100.0
+else:
+ percent = 0
+""",
+ },
+
+ 'lame': {
+ 'type': "encoder",
+ 'target': "mp3",
+ 'inverse-quality': 1,
+ 'cmd': "lame --preset cbr %r --strictly-enforce-ISO %i %o",
+ 'vbr-cmd': "lame --preset standard --vbr-new --nohist --strictly-enforce-ISO %i %o",
+ 'otf-cmd': "lame --preset cbr %r --strictly-enforce-ISO - %o",
+ 'vbr-otf-cmd': "lame --preset standard --vbr-new --nohist --strictly-enforce-ISO - %o",
+ 'status_blocksize': 160,
+ 'bitrate_factor': 1,
+ 'status_start': "%",
+ 'percent_fkt': r"""
+s = string.split(i['buf'], '\r')
+if len(s) >= 2: s=s[-2]
+if len(s) == 1: s=s[0]
+if string.find(s, "%") >= 0: # status reporting starts here
+ y = string.split(s, "/")
+ y1 = string.split(y[1], "(")[0]
+ percent = float(y[0]) / float(y1) * 100.0
+elif string.find(s, "Frame:") >= 0: # older versions, like 3.13
+ y = string.split(s, "/")
+ y0 = string.split(y[0], "[")[-1]
+ y1 = string.split(y[1], "]")[0]
+ percent = float(y0) / float(y1) * 100.0
+else:
+ percent = 0
+""",
+ },
+
+ 'gogo': { # Thanks to José Antonio Pérez Sánchez for the vbr and otf presets
+ 'type': "encoder",
+ 'target': "mp3",
+ 'inverse-quality': 1,
+ 'cmd': "gogo %i %o -b %r",
+ 'vbr-cmd': "gogo %i %o -v %q",
+ 'otf-cmd': "gogo stdin %o -b %r",
+ 'vbr-otf-cmd': "gogo stdin %o -v 4",
+ 'status_blocksize': 160,
+ 'bitrate_factor': 1,
+ 'status_start': "%",
+ 'percent_fkt': r"""
+s = string.split(i['buf'], '\r')
+if len(s) >= 2: s=s[-2]
+if len(s) == 1: s=s[0]
+if string.find(s, "%") >= 0: # status reporting starts here
+ s = replace(s, "\000", " ")
+ y = string.split(s, "/")
+ y0 = string.split(y[0], "{")[-1]
+ y1 = string.split(y[1], "}")[0]
+ percent = float(y0) / float(y1) * 100.0
+else:
+ percent = 0
+""",
+ },
+
+ 'bladeenc': {
+ 'type': "encoder",
+ 'target': "mp3",
+ 'cmd': "bladeenc %i %o -br %r",
+ 'status_blocksize': 180,
+ 'bitrate_factor': 1000,
+ 'status_start': "%",
+ 'percent_fkt': r"""
+s = string.split(i['buf'], '\r')
+if len(s) >= 2: s=s[-2]
+if string.find(s, "Status:") != -1:
+ y = string.split(s[8:])
+ percent = float(string.split(y[0], '%')[0])
+else:
+ percent = 0
+""",
+ },
+
+# xing definitions kindly provided by Sebastian Weber
+ 'xing': {
+ 'type': "encoder",
+ 'target': "mp3",
+ 'cmd': "xingmp3enc -B %r %i %o",
+ 'vbr-cmd': "xingmp3enc -V 100 %i %o",
+ 'otf-cmd': "xingmp3enc -b %r -- %o",
+ 'vbr-otf-cmd': "xingmp3enc -V 100 -- %o",
+ 'status_blocksize': 160,
+ 'bitrate_factor': 1,
+ 'status_start': "%",
+ 'percent_fkt': r"""
+s = string.split(i['buf'], '\r')
+if len(s) >= 2: s = s[-2]
+if string.find(s, "ETA:") != -1:
+ y = string.strip(string.split(s, '%')[0])
+ if len(y) == 0:
+ percent = 0
+ else:
+ percent = float(y)
+else:
+ percent = 0
+""",
+ },
+
+ 'flac': {
+ 'type': "encoder",
+ 'target': "flac",
+ 'vbr-cmd': "flac -o %o %i",
+ 'vbr-otf-cmd': "flac -fr -fb -fc 2 -fp 16 -fs 44100 -o %o",
+ 'status_blocksize': 160,
+ 'status_start': "%",
+ 'percent_fkt': r"""
+s = string.split(i['buf'], '\r')
+if len (s) >= 2: s = s[-2]
+if len (s) == 1: s = s[0]
+y0 = string.rfind(s, ": ")
+y1 = string.find (s, "%", y0)
+if y0 != -1 and y1 != -1:
+ try:
+ percent = float(s[y0 + 1:y1])
+ except ValueError:
+ percent = 0
+else:
+ percent = 0
+""",
+ },
+
+ 'mppenc': {
+ 'type': "encoder",
+ 'target': "mpc",
+ 'can_tag': 0,
+ 'vbr-cmd': "mppenc --standard %i %o",
+ #'vbr-otf-cmd': "mppenc --standard - %o", # doesn't work, needs WAVE
+ 'status_blocksize': 160,
+ 'status_start': "-.-",
+ 'percent_fkt': r"""
+s = string.split(i['buf'], '\r')
+if len(s) >= 3:
+ s = s[-3]
+ s = string.split(string.strip(s))
+ if len(s) >= 3 and s[2] == "kbps" and s[0] != "-.-":
+ percent = float(s[0])
+ else:
+ percent = 0
+""",
+ },
+
+ 'cdparanoia': {
+ 'filters': [[r'\n', r'\r'], [r'(\r)+', r'\r'], [r'(Done\.\r)+', r'Done.\r']],
+ 'type': "ripper",
+ 'cmd': "cdparanoia --abort-on-skip -d %d %n %o",
+ 'otf-cmd': "cdparanoia --abort-on-skip -e -d %d %n -R -",
+ 'status_blocksize': 500,
+ 'status_start': "%",
+ 'status_fkt': r"""
+# (== PROGRESS == [ | 013124 00 ] == :^D * ==)
+# (== PROGRESS == [ > .| 011923 00 ] == :-) . ==)
+tmp = string.split(i['buf'], "\r")
+if len(tmp) >= 2:
+ tmp = tmp[-2] + " "
+ new_status = tmp[17:48] + tmp[49:69] # 68->69 because of newer version
+else:
+ new_status = "Cannot parse status"
+""",
+ 'otf-status_fkt': r"""
+buf = i['buf']
+tmp = string.split(buf, "\n")
+new_status = ""
+if len(tmp) >= 2:
+ tmp = string.split(tmp[-2], " @ ")
+ if tmp[0] == "##: -2 [wrote]":
+ percent = (float(tmp[1]) - (i['track'][START] * CDDA_BLOCKSIZE / 2.0)) / (i['track'][LEN] * CDDA_BLOCKSIZE / 2.0) * 100.0
+ new_status = "[otf - reading, %2i%%]" % percent
+""",
+ 'final_status_fkt': r"""
+last_status="0123456789012345 [ -- error decoding status -- ]" # fallback
+if 0 and cf['_debug']: # disabled for now
+ import jack_version
+ tmpf=open("%s.debug.%02d.txt" % (jack_version.prog_name, exited_proc['track'][NUM]), "w")
+ tmpf.write(exited_proc['buf'])
+ del tmpf
+tmps = string.split(exited_proc['buf'], '\r')
+tmps.reverse()
+for tmp in tmps:
+ if string.find(tmp, "PROGRESS") != -1:
+ last_status = tmp
+ break
+final_status = ("%sx" % jack_functions.pprint_speed(speed)) + last_status[16:48] + "]"
+""",
+ 'otf-final_status_fkt': r"""
+final_status = "[otf - done]"
+""",
+ #'toc': 1, # we can't generate correct freedb IDs with cdparanoia.
+ 'toc_cmd': "cdparanoia -d %d -Q 2>&1",
+ 'toc_fkt': r"""
+while l:
+ l = string.rstrip(l)
+ if l and l[0:5] == "TOTAL":
+ start = 0
+ if l and l == '=' * (len(l)):
+ start = 1
+ elif l and start:
+ l = string.split(l, '.', 1)
+ num = int(l[0])
+ l = string.split(l[1])
+ erg.append([num, int(l[0]), int(l[2]), l[4] == 'OK', l[5] == 'yes', int(l[6]), 1, cf['_bitrate'], cf['_name'] % num])
+ l = p.readline()
+""",
+ },
+
+ 'cdda2wav': {
+ 'type': "ripper",
+ 'cmd': "cdda2wav --no-infofile -H -v 1 -D %d -O wav -t %n %o",
+ 'status_blocksize': 200,
+ 'status_start': "percent_done:",
+ 'status_fkt': r"""
+tmp = string.split(i['buf'], "\r")
+if len(tmp) >= 2:
+ if string.find(tmp[-2], '%') != -1:
+ new_status = "ripping: " + string.strip(tmp[-2])
+ else:
+ new_status = "waiting..."
+else:
+ new_status = "Cannot parse status"
+""",
+ 'final_status_fkt': r"""
+final_status = ("%s" % jack_functions.pprint_speed(speed)) + "x [ DAE done with cdda2wav ]"
+""",
+ 'toc': 1,
+ 'toc_cmd': "cdda2wav --no-infofile -D %d -J -v toc --gui 2>&1",
+ 'toc_fkt': r"""
+while 1:
+ l = p.readline()
+ if not l:
+ break
+ if l[0] == "T" and l[1] in string.digits and l[2] in string.digits and l[3] == ":":
+ num, start, length, type, pre, copy, ch, dummy = string.split(l)[:8]
+ if type == "audio":
+ num = int(num[1:3])
+ start = int(start)
+ length = string.replace(length,".", ":")
+ length = timestrtoblocks(length)
+ pre = pre == "pre-emphasized"
+ copy = copy != "copydenied"
+ ch = [ "none", "mono", "stereo", "three", "quad" ].index(ch)
+ erg.append([num, length, start, copy, pre, ch, 1, cf['_bitrate'], cf['_name'] % (num + 1)])
+""",
+ 'toc_cmd_old': "cdda2wav --no-infofile -D %D -J -v 35 2>&1",
+ 'toc_fkt_old': r"""
+new_c2w = 0
+new_toc1 = 0
+new_toc2 = 0
+new_lengths = []
+new_starts = []
+while 1:
+ l = p.readline()
+ if not l:
+ break
+ l = string.strip(l)
+ # new cdda2wav
+ if starts_with(l, "Table of Contents: total tracks"):
+ new_toc1 = 1
+ continue
+
+ if starts_with(l, "Table of Contents: starting sectors"):
+ new_toc2 = 1
+ new_toc1 = 0
+ new_c2w = 1
+ continue
+
+ if new_toc2 and l and l[0] in string.digits:
+ l = string.split(l, "(")[1:]
+ for i in l:
+ x = string.split(i, ")")[0]
+ x = string.strip(x)
+ try:
+ new_starts.append(int(x))
+ except:
+ pass
+ continue
+
+ if new_toc1 and l and l[0] in string.digits:
+ l = string.split(l, "(")[1:]
+ for i in l:
+ if string.find(i, ":") >= 0:
+ x = string.split(i, ")")[0]
+ x = replace(x, ".", ":")
+ new_lengths.append(timestrtoblocks(x))
+ continue
+
+ # old cdda2wav
+ if l and l[0:11] == "Album title":
+ start = 1
+ elif l and start:
+ l = string.split(l)
+ if l[0] == "Leadout:":
+ start = 0
+ else:
+ num = int(l[0][1:3])
+ if l[6] == "stereo":
+ channels = 2
+ elif l[6] == "mono":
+ channels = 1
+ else:
+ channels = 0
+ t_start = int(l[1])
+ msf = string.split(l[2], ":")
+ sf = string.split(msf[1], ".")
+ t_length = int(sf[1]) + int(sf[0]) * 75 + int(msf[0]) * 60 * 75
+ erg.append([num, t_length, t_start, l[5] == "copyallowed", l[4] != "linear", channels, 1, cf['_bitrate'], cf['_name'] % num])
+if new_c2w and len(new_lengths) == len(new_starts) - 1:
+ for i in range(min(len(new_lengths), len(new_starts))): # this provokes an error if the lists are of different length
+ erg.append([i + 1, new_lengths[i], new_starts[i], 0, 0, 2, 1, cf['_bitrate'], cf['_name'] % (i + 1)])
+""",
+ },
+
+ 'dagrab': {
+ 'type': "ripper",
+ 'cmd': "dagrab -d %d -f %o %n",
+ 'status_blocksize': 100,
+ 'status_start': "total:",
+ 'status_fkt': r"""
+tmp = string.split(i['buf'], "\r")
+if len(tmp) >= 2:
+ if string.find(tmp[-2], 'total:') != -1:
+ new_status = string.strip(tmp[-2])
+ else:
+ new_status = "waiting..."
+else:
+ new_status = "Cannot parse status"
+""",
+ 'final_status_fkt': r"""
+final_status = ("%s" % jack_functions.pprint_speed(speed)) + "x [ DAE done with dagrab ]"
+""",
+ 'toc': 1,
+ 'toc_cmd': "dagrab -d %d -i 2>&1",
+ 'toc_fkt': r"""
+while l:
+ l = string.strip(l)
+ if l and l[0:5] == "track":
+ start = 1
+ elif l and start:
+ l = string.split(l)
+ if l[3] == "leadout":
+ start = 0
+ else:
+ num = int(l[0])
+ channels = 2
+ copy = 0
+ pre = 0
+ t_start = int(l[1]) - 150
+ t_length = int(l[2])
+ erg.append([num, t_length, t_start, copy, pre, channels, 1, cf['_bitrate'], cf['_name'] % num])
+ l = p.readline()
+""",
+ },
+
+ 'tosha': {
+ 'type': "ripper",
+ 'cmd': "tosha -d %d -f wav -t %n -o %o",
+ 'status_blocksize': 100,
+ 'status_start': "total:",
+ 'status_fkt': r"""
+x = string.split(i['buf'], '\r')[-2]
+if string.find(x, 'total:') != -1:
+ new_status = string.strip(string.split(i['buf'], '\r')[-2])
+else:
+ new_status = "waiting..."
+""",
+ 'final_status_fkt': r"""
+final_status = ("%s" % jack_functions.pprint_speed(speed)) + "x [ DAE done with tosha ]"
+""",
+ 'toc': 1,
+ 'toc_cmd': "tosha -d %d -iq 2>&1",
+ 'toc_fkt': r"""
+while l:
+ l = string.rstrip(l)
+ if l:
+ l = string.split(l)
+ num = int(l[0])
+ erg.append([num, 1 + int(l[3]) - int(l[2]), int(l[2]), 0, 0, 2, 1, cf['_bitrate'], cf['_name'] % num])
+ l = p.readline()
+""",
+ },
+
+ 'CDDB.py': {
+ 'type': "toc-reader",
+ 'toc': 1,
+ 'toc_fkt': r"""
+import cdrom
+if not os.path.exists(cf['_cd_device']):
+ error("Device %s does not exist!" % cf['_cd_device'])
+if not os.access(cf['_cd_device'], os.R_OK):
+ error("You don't have permission to access device %s!" % cf['_cd_device'])
+try:
+ device = cdrom.open(cf['_cd_device'])
+ (first, last) = cdrom.toc_header(device)
+except cdrom.error, m:
+ error("Access of CD device %s resulted in error: %s" % (cf['_cd_device'], m[1]))
+
+toc = []
+for i in range(first, last + 1):
+ (min, sec, frame) = cdrom.toc_entry(device, i)
+ toc.append(min * 60 * 75 + sec * 75 + frame)
+(min, sec, frame) = cdrom.leadout(device)
+device.close()
+toc.append(min * 60 * 75 + sec * 75 + frame)
+for i in range(first, last + 1):
+ erg.append([i, toc[i - first + 1] - toc[i - first], toc[i - first] - toc[0], 0, 0, 2, 1, cf['_bitrate'], cf['_name'] % i])
+""",
+ }
+}
+
+helpers['lame-user'] = helpers['lame'].copy()
+helpers['lame-user'].update({'cmd': "lame --preset cbr %r --strictly-enforce-ISO %i %o",
+ 'vbr-cmd': "lame -V %q --vbr-new --nohist --strictly-enforce-ISO %i %o",
+ 'otf-cmd': "lame --preset cbr %r --strictly-enforce-ISO - %o",
+ 'vbr-otf-cmd': "lame -V %q --vbr-new --nohist --strictly-enforce-ISO - %o", })
+
+def init():
+ # import plugin
+ jack_plugins.import_helpers()
+
+ # compile exec strings
+ for h in helpers.keys():
+ for i in helpers[h].keys():
+ if i[-4:] == "_fkt":
+ helpers[h][i] = compile(helpers[h][i], '<string>', 'exec')
+
+ # compile filters
+ for h in helpers.keys():
+ if helpers[h].has_key('filters'):
+ newf = []
+ for i in helpers[h]['filters']:
+ newf.append([re.compile(i[0]), i[1]])
+ helpers[h]['filters'] = newf