From c7d02d3733aa4f04266c713de1a652cb84319a31 Mon Sep 17 00:00:00 2001 From: Evan Harris Date: Thu, 15 Sep 2022 04:31:57 -0500 Subject: [PATCH 1/3] Add config file option to set cdparanoia command Resolves #220 Partially addresses #244 Provides workaround for #234 Signed-off-by: Evan Harris --- whipper/command/main.py | 5 +++++ whipper/program/cdparanoia.py | 15 +++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/whipper/command/main.py b/whipper/command/main.py index 8e06939a..48cdb8f7 100644 --- a/whipper/command/main.py +++ b/whipper/command/main.py @@ -13,12 +13,17 @@ from whipper.common import common, directory, config from whipper.extern.task import task from whipper.program.utils import eject_device +from whipper.program import cdparanoia import logging logger = logging.getLogger(__name__) def main(): + cdparanoia_cmd = config.Config().get('main', 'cdparanoia') + if cdparanoia_cmd: + cdparanoia.setCdParanoiaCommand(cdparanoia_cmd) + server = config.Config().get_musicbrainz_server() https_enabled = server['scheme'] == 'https' try: diff --git a/whipper/program/cdparanoia.py b/whipper/program/cdparanoia.py index 5c4b7793..80fbe9c4 100644 --- a/whipper/program/cdparanoia.py +++ b/whipper/program/cdparanoia.py @@ -35,6 +35,7 @@ import logging logger = logging.getLogger(__name__) +cdparanoia = 'cd-paranoia' class FileSizeError(Exception): """The given path does not have the expected size.""" @@ -69,6 +70,12 @@ class ChecksumException(Exception): _ERROR_RE = re.compile("^scsi_read error:") + +def setCdParanoiaCommand(cmd): + global cdparanoia + cdparanoia = cmd + + # from reading cdparanoia source code, it looks like offset is reported in # number of single-channel samples, ie. 2 bytes (word) per unit, and absolute @@ -271,10 +278,10 @@ def start(self, runner): bufsize = 1024 if self._overread: - argv = ["cd-paranoia", "--stderr-progress", + argv = [cdparanoia, "--stderr-progress", "--sample-offset=%d" % self._offset, "--force-overread", ] else: - argv = ["cd-paranoia", "--stderr-progress", + argv = [cdparanoia, "--stderr-progress", "--sample-offset=%d" % self._offset, ] if self._device: argv.extend(["--force-cdrom-device", self._device, ]) @@ -573,7 +580,7 @@ def stop(self): def getCdParanoiaVersion(): getter = common.VersionGetter('cd-paranoia', - ["cd-paranoia", "-V"], + [cdparanoia, "-V"], _VERSION_RE, "%(version)s %(release)s") @@ -599,7 +606,7 @@ class AnalyzeTask(ctask.PopenTask): def __init__(self, device=None): # cdparanoia -A *always* writes cdparanoia.log self.cwd = tempfile.mkdtemp(suffix='.whipper.cache') - self.command = ['cd-paranoia', '-A'] + self.command = [cdparanoia, '-A'] if device: self.command += ['-d', device] From a72fd8fa78f3736ae29b92201dc510d4d84e8e64 Mon Sep 17 00:00:00 2001 From: Evan Harris Date: Thu, 15 Sep 2022 14:06:11 -0500 Subject: [PATCH 2/3] Added documentation for cdparanoia config to README Signed-off-by: Evan Harris --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b39c31f3..cd3cfd9e 100644 --- a/README.md +++ b/README.md @@ -253,6 +253,7 @@ path_filter_posix = True ; replace illegal chars in *nix OSes with _ path_filter_vfat = False ; replace illegal chars in VFAT filesystems with _ path_filter_whitespace = False ; replace all whitespace chars with _ path_filter_printable = False ; replace all non printable ASCII chars with _ +# cdparanoia = cdparanoia ; cdparanoia executable to use. Default is cd-paranoia [musicbrainz] server = https://musicbrainz.org ; use MusicBrainz server at host[:port] From bb46eea3f7005d6d0570468b820fd7300f461fe2 Mon Sep 17 00:00:00 2001 From: Evan Harris Date: Mon, 26 Sep 2022 13:06:54 -0500 Subject: [PATCH 3/3] Added ability to set cdparanoia command in per-drive config Signed-off-by: Evan Harris --- README.md | 9 ++++++++- whipper/command/cd.py | 16 +++++++++++++--- whipper/common/config.py | 4 ++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cd3cfd9e..4011faea 100644 --- a/README.md +++ b/README.md @@ -253,7 +253,6 @@ path_filter_posix = True ; replace illegal chars in *nix OSes with _ path_filter_vfat = False ; replace illegal chars in VFAT filesystems with _ path_filter_whitespace = False ; replace all whitespace chars with _ path_filter_printable = False ; replace all non printable ASCII chars with _ -# cdparanoia = cdparanoia ; cdparanoia executable to use. Default is cd-paranoia [musicbrainz] server = https://musicbrainz.org ; use MusicBrainz server at host[:port] @@ -265,6 +264,14 @@ defeats_cache = True ; whether the drive is capable of defeating the audio cac read_offset = 6 ; drive read offset in positive/negative frames (no leading +) # do not edit the values 'vendor', 'model', and 'release'; they are used by whipper to match the drive +[drive:PIONEER%20%3ABD-RW%20%20%20BDR-209D%3A1.10] +defeats_cache = True +read_offset = 667 +cdparanoia = cdparanoia ; cdparanoia executable to use. Default is cd-paranoia + ; cd-paranoia has a bug that makes drives with large read_offset + ; unusable, see https://github.com/whipper-team/whipper/issues/234 + + # command line defaults for `whipper cd rip` [whipper.cd.rip] unknown = True diff --git a/whipper/command/cd.py b/whipper/command/cd.py index cee7a018..df0f1c3a 100644 --- a/whipper/command/cd.py +++ b/whipper/command/cd.py @@ -179,16 +179,26 @@ def do(self): # result - self.program.result.cdrdaoVersion = cdrdao.version() - self.program.result.cdparanoiaVersion = \ - cdparanoia.getCdParanoiaVersion() + info = drive.getDeviceInfo(self.device) if info: + try: + cdparanoia_cmd = self.config.getCdparanoia(*info) + logger.info("using configured cdparanoia command %s", cdparanoia_cmd) + cdparanoia.setCdParanoiaCommand(cdparanoia_cmd) + except KeyError: + pass + try: self.program.result.cdparanoiaDefeatsCache = \ self.config.getDefeatsCache(*info) except KeyError as e: logger.debug('got key error: %r', (e, )) + + self.program.result.cdrdaoVersion = cdrdao.version() + self.program.result.cdparanoiaVersion = \ + cdparanoia.getCdParanoiaVersion() + self.program.result.artist = self.program.metadata \ and self.program.metadata.artist \ or 'Unknown Artist' diff --git a/whipper/common/config.py b/whipper/common/config.py index 45744e23..af6b367f 100644 --- a/whipper/common/config.py +++ b/whipper/common/config.py @@ -101,6 +101,10 @@ def getDefeatsCache(self, vendor, model, release): option = self._getDriveOption(vendor, model, release, 'defeats_cache') return option == 'True' + def getCdparanoia(self, vendor, model, release): + """Get the cdparanoia command for the given drive.""" + return self._getDriveOption(vendor, model, release, 'cdparanoia') + def _findDriveSection(self, vendor, model, release): for name in self._parser.sections(): if not name.startswith('drive:'):