From 9395fd52ec9fbdf87cf5e3f39fbbcb3b6a3e2be2 Mon Sep 17 00:00:00 2001 From: Mikhail Osipov Date: Sun, 10 Nov 2013 20:39:54 +0400 Subject: wav decode without popen --- cutter.py | 4 +- cutter/formats/command.py | 5 +-- cutter/formats/decoder.py | 100 +++++++++++++++++++++++++++++++++------------- cutter/formats/encoder.py | 4 +- cutter/splitter.py | 8 ++-- 5 files changed, 81 insertions(+), 40 deletions(-) diff --git a/cutter.py b/cutter.py index 5dcad53..6b0cbcd 100755 --- a/cutter.py +++ b/cutter.py @@ -250,7 +250,7 @@ def find_cuefile(path): for file in os.listdir(path): fullname = os.path.join(path, file) if os.path.isfile(fullname) and file.endswith(".cue"): - return fullname + return os.path.normpath(fullname) printerr("no cue file") sys.exit(1) @@ -294,8 +294,6 @@ def main(): return 1 cuesheet.dir = os.path.dirname(cuepath) - if cuesheet.dir: - cuesheet.dir += "/" switch(options.dump, { "cue": lambda: print_cue(cuesheet), diff --git a/cutter/formats/command.py b/cutter/formats/command.py index 6be748d..d6db0ae 100644 --- a/cutter/formats/command.py +++ b/cutter/formats/command.py @@ -36,7 +36,7 @@ class Command: def get_status(self): return self.status, self.status_msg - def close(self, msg=""): + def close(self): if self.proc is None: return @@ -44,9 +44,6 @@ class Command: if self.status and self.proc.stderr: self.status_msg = to_unicode(self.proc.stderr.read()) - if msg and not self.status_msg: - self.status_msg = msg - if self.status < 0: self.status = strsignal(-self.status) diff --git a/cutter/formats/decoder.py b/cutter/formats/decoder.py index fb2ad3c..62a2a50 100644 --- a/cutter/formats/decoder.py +++ b/cutter/formats/decoder.py @@ -12,7 +12,7 @@ class DecoderError(Exception): class StreamInfo: pass -class Decoder: +class BaseDecoder: class Reader: def __init__(self, stream, nframes): self.stream = stream @@ -45,21 +45,18 @@ class Decoder: return data - def __init__(self, handler, filename, options=None): + def __init__(self, handler): + self.reader = None self.handler = handler - args = self.handler.decode(filename) - self.command = " ".join(map(quote, args)) - - self.proc = Command(args, stdout=PIPE, stderr=PIPE) - if not self.proc.ready(): - return - + def _init_reader(self, source): try: - self.reader = wave.open(self.proc.stdout, "r") + self.reader = wave.open(source, "r") except Exception as exc: - self.proc.stdout.close() - self.proc.close("Exception: wave.open: %s" % repr(exc)) + self.close() + + self.status = "Exception" + self.status_msg = "wave.open: %s" % exc return self._channels = self.reader.getnchannels() @@ -67,7 +64,7 @@ class Decoder: self._sample_rate = self.reader.getframerate() def ready(self): - return self.proc.ready() + return self.reader is not None def channels(self): return self._channels @@ -106,25 +103,65 @@ class Decoder: return self.Reader(self, nframes) - def get_command(self): - return self.command + def describe(self): + return "-" def get_status(self): - return self.proc.get_status() + if hasattr(self, "status"): + return self.status, self.status_msg + + return None, "" def close(self): - if self.proc.ready(): + if self.reader: self.reader.close() - self.proc.stdout.close() - self.proc.close() + self.reader = None def __del__(self): self.close() -class DummyDecoder(Decoder): - class DummyReader(Decoder.Reader): +class WavDecoder(BaseDecoder): + def __init__(self, handler, filename, options=None): + BaseDecoder.__init__(self, handler) + + self.filename = filename + self._init_reader(filename) + + def describe(self): + return self.filename + +class AnyDecoder(BaseDecoder): + def __init__(self, handler, filename, options=None): + BaseDecoder.__init__(self, handler) + + args = self.handler.decode(filename) + self.command = " ".join(map(quote, args)) + + self.proc = Command(args, stdout=PIPE, stderr=PIPE) + if not self.proc.ready(): + return + + self._init_reader(self.proc.stdout) + + def describe(self): + return self.command + + def get_status(self): + if self.proc.status_msg: + return self.proc.get_status() + + return BaseDecoder.get_status(self) + + def close(self): + if self.proc.ready(): + BaseDecoder.close(self) + self.proc.stdout.close() + self.proc.close() + +class DummyDecoder: + class DummyReader(BaseDecoder.Reader): def __init__(self, *args): - Decoder.Reader.__init__(self, *args) + BaseDecoder.Reader.__init__(self, *args) def info(self): return self.stream.info() @@ -132,8 +169,11 @@ class DummyDecoder(Decoder): def read(self, *args): return [] - def __init__(self, *args, **kwargs): - Decoder.__init__(self, *args, **kwargs) + def __init__(self, orig): + self.orig = orig + + def __getattr__(self, attr): + return getattr(self.orig, attr) def seek(self, *args): pass @@ -143,7 +183,13 @@ class DummyDecoder(Decoder): class DecoderHandler(Handler): def open(self, filename, options=None): - if options and options.dry_run: - return DummyDecoder(self.handler, filename, options) + if self.handler.name == "wav": + cls = WavDecoder else: - return Decoder(self.handler, filename, options) + cls = AnyDecoder + + stream = cls(self.handler, filename, options) + if options and options.dry_run: + stream = DummyDecoder(stream) + + return stream diff --git a/cutter/formats/encoder.py b/cutter/formats/encoder.py index 3f236c0..cbf61a4 100644 --- a/cutter/formats/encoder.py +++ b/cutter/formats/encoder.py @@ -53,13 +53,13 @@ class Encoder: return getattr(self.fileobj, attr) def __init__(self, handler, reader, filename, options): + self.proc = None self.handler = handler args = self.handler.encode(filename, options, reader.info()) self.command = " ".join(map(quote, args)) if options.dry_run: - self.proc = None return self.proc = Command(args, stdin=PIPE) @@ -90,7 +90,7 @@ class Encoder: progress.finish() - def get_command(self): + def describe(self): return self.command def get_status(self): diff --git a/cutter/splitter.py b/cutter/splitter.py index 18bfecb..e00cdf2 100644 --- a/cutter/splitter.py +++ b/cutter/splitter.py @@ -191,13 +191,13 @@ class Splitter: debug("skip file %s: no tracks", quote(file.name)) continue - path = self.cue.dir + file.name + path = os.path.join(self.cue.dir, file.name) if not os.path.exists(path): real = self.find_realfile(file.name) if not real: printerr("no such file %s", quote(file.name)) sys.exit(1) - path = self.cue.dir + real + path = os.path.join(self.cue.dir, real) lst.append(self.File(file, path)) @@ -271,8 +271,8 @@ class Splitter: def print_command_error(name, stream): status, msg = stream.get_status() - cmd = stream.get_command() - printerr("%s failed (%s), command: %s", name, status, cmd) + cmd = stream.describe() + printerr("%s failed (%s), cmd: %s", name, status, cmd) for line in msg.split("\n"): if len(line): printf("> %s\n", line) -- cgit v1.2.3-70-g09d2