Python CD-DA ripper preferring accuracy over speed

Overview

Whipper

license Build Status GitHub (pre-)release IRC GitHub Stars GitHub Issues GitHub contributors

Whipper is a Python 3 (3.6+) CD-DA ripper based on the morituri project (CDDA ripper for *nix systems aiming for accuracy over speed). It started just as a fork of morituri - which development seems to have halted - merging old ignored pull requests, improving it with bugfixes and new features. Nowadays whipper's codebase diverges significantly from morituri's one.

Whipper is currently developed and tested only on Linux distributions but may work fine on other *nix OSes too.

In order to track whipper's latest changes it's advised to check its commit history (README and CHANGELOG files may not be comprehensive).

Table of content

Rationale

For a detailed description, see morituri's wiki page: The Art of the Rip.

Features

  • Detects correct read offset (in samples)
  • Detects whether ripped media is a CD-R
  • Has ability to defeat cache of drives
  • Performs Test & Copy rips
  • Verifies rip accuracy using the AccurateRip database
  • Uses MusicBrainz for metadata lookup
  • Supports reading the pre-emphasis flag embedded into some CDs (and correctly tags the resulting rip)
    • Currently whipper only reports the pre-emphasis flag value stored in the TOC
  • Detects and rips non digitally silent Hidden Track One Audio (HTOA)
  • Provides batch ripping capabilities
  • Provides templates for file and directory naming
  • Supports lossless encoding of ripped audio tracks (FLAC)
  • Allows extensibility through external logger plugins

Changelog

See CHANGELOG.md.

For detailed information, please check the commit history.

Installation

Whipper still isn't available as an official package in every Linux distributions so, in order to use it, it may be necessary to build it from its source code.

Docker

You can easily install whipper without needing to care about the required dependencies by making use of the automatically built images hosted on Docker Hub:

docker pull whipperteam/whipper

Please note that, right now, Docker Hub only builds whipper images for the amd64 architecture: if you intend to use them on a different one, you'll need to build the images locally (as explained below).

Building the Docker image locally is required in order to make it work on Arch Linux (and its derivatives) because of a group permission issue (for more details see issue #499).

To build the Docker image locally just issue the following command (it relies on the Dockerfile included in whipper's repository):

optical_gid=$(getent group optical | cut -d: -f3) uid=$(id -u) docker build --build-arg optical_gid --build-arg uid -t whipperteam/whipper .

It's recommended to create an alias for a convenient usage:

alias whipper="docker run -ti --rm --device=/dev/cdrom \
    --mount type=bind,source=${HOME}/.config/whipper,target=/home/worker/.config/whipper \
    --mount type=bind,source=${PWD}/output,target=/output \
    whipperteam/whipper"

You should put this e.g. into your .bash_aliases. Also keep in mind to substitute the path definitions to something that fits to your needs (e.g. replace … -v ${PWD}/output:/output … with … -v ${HOME}/ripped:/output \ …).

Essentially, what this does is to map the /home/worker/.config/whipper and ${PWD}/output (or whatever other directory you specified) on your host system to locations inside the Docker container where the files can be written and read. These directories need to exist on your system before you can run the container:

mkdir -p "${HOME}/.config/whipper" "${PWD}/output"

Please note that the example alias written above only provides access to a single disc drive: if you've got many you will need to customise it in order to use all of them in whipper's Docker container.

Finally you can test the correct installation as such:

whipper -v
whipper drive list

Package

This is a noncomprehensive summary which shows whipper's packaging status (unofficial repositories are probably not included):

Packaging status

NOTE: if installing whipper from an unofficial repository please keep in mind it is your responsibility to verify that the provided content is safe to use.

Building

If you are building from a source tarball or checkout, you can choose to use whipper installed or uninstalled but first install all the required dependencies.

Required dependencies

Whipper relies on the following packages in order to run correctly and provide all the supported features:

  • cd-paranoia, for the actual ripping
    • To avoid bugs it's advised to use cd-paranoia versions ≥ 10.2+0.94+2-2
    • The package named libcdio-utils, available on Debian and Ubuntu, is affected by a bug (except for Debian testing/sid where a separate cd-paranoia package has been added): it doesn't include the cd-paranoia binary (needed by whipper). For more details see: #888053 (Debian), #889803 (Debian) and #1750264 (Ubuntu).
  • cdrdao, for session, TOC, pre-gap, and ISRC extraction
  • GObject Introspection, to provide GLib-2.0 methods used by task.py
  • PyGObject, required by task.py
  • musicbrainzngs, for metadata lookup
  • mutagen, for tagging support
  • setuptools, for installation, plugins support
  • pycdio, for drive identification (required for drive offset and caching behavior to be stored in the configuration file).
    • To avoid bugs it's advised to use the most recent pycdio version with the corresponding libcdio release or, if stuck to old pycdio versions, 0.20/0.21 with libcdio0.900.94. All other combinations won't probably work.
  • discid, for calculating Musicbrainz disc id.
  • ruamel.yaml, for generating well formed YAML report logfiles
  • libsndfile, for reading wav files
  • flac, for reading flac files
  • sox, for track peak detection
  • git or mercurial
    • Required either when running whipper without installing it or when building it from its source code (code cloned from a git/mercurial repository).

Some dependencies aren't available in the PyPI. They can be probably installed using your distribution's package manager:

PyPI installable dependencies are listed in the requirements.txt file and can be installed issuing the following command:

pip3 install -r requirements.txt

Optional dependencies

  • Pillow, for completely supporting the cover art feature (embed and complete option values won't work otherwise).
  • docutils, to build the man pages.

These dependencies are not listed in the requirements.txt. To install them, just issue the following command:

pip3 install Pillow docutils

Fetching the source code

Change to a directory where you want to put whipper source code (for example, $HOME/dev/ext or $HOME/prefix/src)

git clone https://github.com/whipper-team/whipper.git
cd whipper

Finalizing the build

Install whipper: python3 setup.py install

Note that, depending on the chosen installation path, this command may require elevated rights.

Usage

Whipper currently only has a command-line interface called whipper which is self-documenting: whipper -h gives you the basic instructions.

Whipper implements a tree of commands: for example, the top-level whipper command has a number of sub-commands.

Positioning of arguments is important:

whipper cd -d (device) rip

is correct, while

whipper cd rip -d (device)

is not, because the -d argument applies to the cd command.

A more complete set of usage instructions can be found in the whipper man pages.

Getting started

The simplest way to get started making accurate rips is:

  1. Pick a relatively popular CD that has a good chance of being in the AccurateRip database

  2. Analyze the drive's caching behavior

    whipper drive analyze

  3. Find the drive's offset.

    Consult the AccurateRip's CD Drive Offset database for your drive. Drive information can be retrieved with whipper drive list.

    whipper offset find -o insert-numeric-value-here

    If you omit the -o argument, whipper will try a long, popularity-sorted list of drive offsets.

    If you can not confirm your drive offset value but wish to set a default regardless, set read_offset = insert-numeric-value-here in whipper.conf.

    Offsets confirmed with whipper offset find are automatically written to the configuration file.

    If specifying the offset manually, please note that: if positive it must be written as a number without sign (ex: +102 -> 102), if negative it must include the sign too (ex: -102 -> -102).

  4. Rip the disc by running

    whipper cd rip

Configuration file documentation

The configuration file is stored in $XDG_CONFIG_HOME/whipper/whipper.conf, or $HOME/.config/whipper/whipper.conf if $XDG_CONFIG_HOME is undefined.

See XDG Base Directory Specification and ConfigParser with inline_comment_prefixes=(';').

The configuration file consists of newline-delineated [sections] containing key = value pairs. The sections [main] and [musicbrainz] are special config sections for options not accessible from the command line interface. Sections beginning with drive are written by whipper; certain values should not be edited. Inline comments can be added using ;.

Example configuration demonstrating all [main] and [musicbrainz] options:

[main]
path_filter_dot = True			; replace leading dot with _
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 _

[musicbrainz]
server = https://musicbrainz.org	; use MusicBrainz server at host[:port]
# use http as scheme if connecting to a plain http server. Example below:
# server = http://example.com:8080

[drive:HL-20]
defeats_cache = True			; whether the drive is capable of defeating the audio cache
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

# command line defaults for `whipper cd rip`
[whipper.cd.rip]
unknown = True
output_directory = ~/My Music
# Note: the format char '%' must be represented '%%'.
# Do not add inline comments with an unescaped '%' character (else an 'InterpolationSyntaxError' will occur).
track_template = new/%%A/%%y - %%d/%%t - %%n
disc_template =  new/%%A/%%y - %%d/%%A - %%d
# ...

Running uninstalled

To make it easier for developers, you can run whipper straight from the source checkout:

python3 -m whipper -h

Logger plugins

Whipper allows using external logger plugins to customize the template of .log files.

The available plugins can be listed with whipper cd rip -h. Specify a logger to rip with by passing -L loggername:

whipper cd rip -L eac

Whipper searches for logger plugins in the following paths:

  • $XDG_DATA_HOME/whipper/plugins

  • Paths returned by the following Python instruction:

    [x + '/whipper/plugins' for x in site.getsitepackages()]

  • If whipper is run in a virtualenv, it will use these alternative instructions (from distutils.sysconfig):

    • get_python_lib(plat_specific=False, standard_lib=False, prefix='/usr/local') + '/whipper/plugins'
    • get_python_lib(plat_specific=False, standard_lib=False) + '/whipper/plugins'

On a default Debian/Ubuntu installation, the following paths are searched by whipper:

  • $HOME/.local/share/whipper/plugins
  • /usr/local/lib/python3.X/dist-packages/whipper/plugins
  • /usr/lib/python3.X/dist-packages/whipper/plugins

Where X stands for the minor version of the Python 3 release available on the system.

Official logger plugins

I suggest using whipper's default logger unless you've got particular requirements.

License

Licensed under the GNU GPLv3 license.

Copyright (C) 2009 Thomas Vander Stichele
Copyright (C) 2016-2021 The Whipper Team: JoeLametta, Samantha Baldwin,
                        Merlijn Wajer, Frederik “Freso” S. Olesen, et al.

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 3 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA

Contributing

Make sure you have the latest copy from our git repository. Where possible, please include tests for new or changed functionality. You can run tests with python3 -m unittest discover from your source checkout.

Developer Certificate of Origin (DCO)

To make a good faith effort to ensure licensing criteria are met, this project requires the Developer Certificate of Origin (DCO) process to be followed.

The Developer Certificate of Origin (DCO) is a document that certifies you own and/or have the right to contribute the work and license it appropriately. The DCO is used instead of a much more annoying CLA (Contributor License Agreement). With the DCO, you retain copyright of your own work :). The DCO originated in the Linux community, and is used by other projects like Git and Docker.

The DCO agreement is shown below and it's also available online: HERE.

Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.

DCO Sign-Off Methods

The DCO requires a sign-off message in the following format appear on each commit in the pull request:

Signed-off-by: Full Name <email>

The DCO text can either be manually added to your commit body, or you can add either -s or --signoff to your usual Git commit commands. If you forget to add the sign-off you can also amend a previous commit with the sign-off by running git commit --amend -s.

Bug reports & feature requests

Please use the issue tracker to report any bugs or to file feature requests.

When filing bug reports, please run the failing command with the environment variable WHIPPER_DEBUG set. For example:

WHIPPER_DEBUG=DEBUG WHIPPER_LOGFILE=whipper.log whipper offset find
gzip whipper.log

And attach the gzipped log file to your bug report.

Without WHIPPER_LOGFILE set, logging messages will go to stderr. WHIPPER_DEBUG accepts a string of the default python logging levels.

Credits

Thanks to:

And to all the contributors.

Links

You can find us and talk about the project on:

Other relevant links:

Comments
  • Grab cover art from MusicBrainz/Cover Art Archive and add it to the resulting whipper rips

    Grab cover art from MusicBrainz/Cover Art Archive and add it to the resulting whipper rips

    Submitted as a part of GCI competition

    Description Fixes: #50

    Add option --cover-art to whipper cd rip command which accepts three values:

    • file: save the downloaded cover image as standalone file in the rip folder (named cover.jpg)
    • embed: embed the download cover image into all the ripped audio tracks (no standalone file will be kept)
    • complete: save standalone cover image as standalone file and embed it into all the ripped audio tracks (file + embed)

    Every cover art is fetched from the Cover Art Archive as JPEG thumbnail with a maximum dimension of 500px using musicbrainzngs. Other supported values for the thumbnails are 250, 500 and 1200 (currently only some images have a corresponding 1200px sized thumbnail).

    This feature introduces an optional dependency on the Pillow module which is required for the decoding of the cover file (required by the embed and complete option values).

    Problems

    • EmbedPicTureTask shouldn't be a task.
    • The test checks only getCoverArt's functionality (embedding isn't tested)
    opened by ABCbum 40
  • Remove gstreamer dependency

    Remove gstreamer dependency

    It would be nice to rip out the gstreamer dependency. This means:

    1. Writing code for peak calculation using sox (we have this ready)
    2. Encoding using the flac tool (we have this ready)
    3. AR calculation using the accuraterip_checksum tool (we have this, kinda)

    For 3 - I will only for V1 first. Adding V2 support is relatively easy, but that should be done separately.

    Accepted Feature 
    opened by MerlijnWajer 39
  • Added --keep-going option to cd rip command

    Added --keep-going option to cd rip command

    Implemented the option (-k, --keep-going) to continue ripping the CD even if one track fails to rip (as @xmixahlx suggested in #128). So this command:

    whipper cd rip --keep-going --max-retries 8 -O some/folder
    

    Would try to rip a problematic track 8 times, then continue on to the next track on the CD if the track fails to rip.

    Signed-off-by: blueblots [email protected]

    opened by blueblots 33
  • accuraterip-checksum: convert to python C extension

    accuraterip-checksum: convert to python C extension

    • calculate v1 and v2 checksums at once
    • let libsndfile handle both WAV and FLAC

    I tested this using the following script:

    #!/usr/bin/env python
    
    import accuraterip
    
    v1, v2 = accuraterip.compute('Nirvana - Nevermind (Remastered)/01. Nirvana - Smells Like Teen Spirit.flac', 1, 12)
    assert(v1 == 0xA0D81775)
    assert(v2 == 0x280694C8)
    
    v1, v2 = accuraterip.compute('Nirvana - Nevermind (Remastered)/02. Nirvana - In Bloom.flac', 2, 12)
    assert(v1 == 0x92EC1D7D)
    assert(v2 == 0x1AE5FD7A)
    
    v1, v2 = accuraterip.compute('Nirvana - Nevermind (Remastered)/12. Nirvana - Something in the Way - Endless, Nameless.flac', 12, 12)
    assert(v1 == 0x3EAA3B67)
    assert(v2 == 0x14C921A5)
    
    print("OK")
    

    This may need some more testing. When called with invalid input files, compute() returns None, None. Note that 0 may be a valid checksum, so the statement if not v1_sum in accurip.py may have produced false negatives in the past.

    opened by mtdcr 30
  • Ability to skip unrippable track

    Ability to skip unrippable track

    I have some CDs that have been damaged, whipper stops when it hits a damaged track, ie. CRITICAL:morituri.command.cd:Giving up on track 4 after 5 times

    Could a flag be introduced like -c 'Continue' when a track is unrippable?

    Accepted Priority: medium Feature Needed: discussion 
    opened by brendan-pike 30
  • libcdio-paranoia instead of cdparanoia

    libcdio-paranoia instead of cdparanoia

    libcdio-paranoia appears to be maintained: https://github.com/rocky/libcdio-paranoia

    It would probably be easier to file bugs against this project compared to the original cdparanoia so in case we see a patch for the Julie Roberts bug, it could end up in the official repositories of the distributions.

    Accepted Feature Needed: documentation 
    opened by 45054 29
  • AccurateRip V2 support

    AccurateRip V2 support

    • output path no longer has fallbacks
    • refactor accuraterip cache
    • use requests to download accuraterip entries
    • add tests for accuraterip functionality
    • remove gobject support from accuraterip-checksum calculation
    • default track template now includes extension
    • begin to remove support for continuing rip
    • begin to use print instead of sys.stdout.write() throughout
    opened by RecursiveForest 27
  • whipper not picking up all settings in whipper.conf

    whipper not picking up all settings in whipper.conf

    This used to work a month or so ago. I have my config in $HOME/.config/whipper/whipper.conf which should be the same as $XDG_CONFIG_HOME/whipper/whipper.conf on my system anyway. The config looks like:

    [main] path_filter_fat = True path_filter_special = False

    [drive:TSSTcorp%3ACDDVDW%20TS-U633J%20%3ATM00] vendor = TSSTcorp model = CDDVDW TS-U633J release = TM00 read_offset = 6 defeats_cache = True

    [rip.cd.rip] unknown = True output_directory = /home/eivind/rippers/whipper track_template = %%r/%%A/%%d (%%y)/[%%t] %%n disc_template = %%r/%%A/%%d (%%y)/%%A - %%d (%%y) profile = flac

    The settings under [main] and [drive:*] seems to be picked up as before but the settings under [rip.cd.rip] are not and those values fall back to default. This is happening with current git checkout as of today.

    Bug 
    opened by mokkurkalve 24
  • Python 3 port

    Python 3 port

    Given the imminent end-of-life for Python 2, I didn't bother making the codebase compatible with both.

    I successfully ripped a CD with this patch using Python 3, but I'm not confident that I hit every code path. Hopefully this is useful as a jumping-off point for someone who wants to finish the port.

    opened by ddevault 22
  • Refactor cdrdao toc/table functions into Task and provide progress output

    Refactor cdrdao toc/table functions into Task and provide progress output

    This PR fixes issue #299 and also refactors the cdrdao read toc function into a Task as a prerequisite for this. I've rebased my changes against the upstream/develop branch and ran a test rip just now.

    A question. Now that at present we aren't using fast_toc, do we really need to read the TOC and table separately, when it appears they contain the same data, except for the offset in the table. Would shave some time off ripping if it's possible to only need to do it once, but I feel such a change would be out of scope of this PR.

    Fixes #299.

    opened by jtl999 22
  • failing unittests in systemd-nspawn container

    failing unittests in systemd-nspawn container

    Hello, I'd like to move whipper to the official arch linux repositories. For this I need to package whipper in a clean chroot/systemd-nspawn container. Whipper is building, but the unit tests are failing:

    ...............WARNING:morituri.common.program:Track 01: not matched in AccurateRip database
    WARNING:morituri.common.program:Track 01: none of the responses matched.
    WARNING:morituri.common.program:Track 10: not matched in AccurateRip database
    WARNING:morituri.common.program:Track 10: none of the responses matched.
    ......................................................WARNING:morituri.program.cdrdao:cdrdao version detection failed: could not find version
    F..WARNING:morituri.common.mbngs:Release with ID '3451f29c-9bb8-4cc5-bfcc-bd50104b94f8' (Jeff Buckley - Everybody Here Wants You) does not have a date
    ............F
    ======================================================================
    FAIL: testGetVersion (morituri.test.test_program_cdrdao.VersionTestCase)
    testGetVersion
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/lib/python2.7/site-packages/twisted/internet/defer.py", line 150, in maybeDeferred
        result = f(*args, **kw)
      File "/usr/lib/python2.7/site-packages/twisted/internet/utils.py", line 201, in runWithWarningsSuppressed
        reraise(exc_info[1], exc_info[2])
      File "/usr/lib/python2.7/site-packages/twisted/internet/utils.py", line 197, in runWithWarningsSuppressed
        result = f(*a, **kw)
      File "/build/whipper/src/whipper-0.5.1/morituri/test/test_program_cdrdao.py", line 15, in testGetVersion
        self.failUnless(v)
      File "/usr/lib/python2.7/site-packages/twisted/trial/_synctest.py", line 395, in assertTrue
        super(_Assertions, self).assertTrue(condition, msg)
      File "/usr/lib/python2.7/unittest/case.py", line 422, in assertTrue
        raise self.failureException(msg)
    FailTest: None is not true
    
    ======================================================================
    FAIL: testAll (morituri.test.test_common_directory.DirectoryTestCase)
    testAll
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/usr/lib/python2.7/site-packages/twisted/internet/defer.py", line 150, in maybeDeferred
        result = f(*args, **kw)
      File "/usr/lib/python2.7/site-packages/twisted/internet/utils.py", line 201, in runWithWarningsSuppressed
        reraise(exc_info[1], exc_info[2])
      File "/usr/lib/python2.7/site-packages/twisted/internet/utils.py", line 197, in runWithWarningsSuppressed
        result = f(*a, **kw)
      File "/build/whipper/src/whipper-0.5.1/morituri/test/test_common_directory.py", line 13, in testAll
        self.failUnless(path.startswith('/home'))
      File "/usr/lib/python2.7/site-packages/twisted/trial/_synctest.py", line 395, in assertTrue
        super(_Assertions, self).assertTrue(condition, msg)
      File "/usr/lib/python2.7/unittest/case.py", line 422, in assertTrue
        raise self.failureException(msg)
    FailTest: False is not true
    
    ----------------------------------------------------------------------
    Ran 85 tests in 6.352s
    
    FAILED (failures=2)
    ==> ERROR: A failure occurred in check().
        Aborting...
    ==> ERROR: Build failed, check /var/lib/archbuild/extra-x86_64/chris/build
    extra-x86_64-build -- -I   5.20s user 1.55s system 48% cpu 13.907 total
    

    Do I miss a dependency or is this an issue because of the chroot?

    My dependencies:

    accuraterip-checksum' 
    cddb-py'              
    cdparanoia'           
    cdrdao'               
    libsndfile'           
    mutagen'              
    python2-musicbrainzngs
    python2-pycdio'       
    python2-setuptools'   
    sox'                  
    python2-gobject2 #only for the make process
    python2-twisted #only for the unit tests
    
    Bug 
    opened by shibumi 21
  • TOCError: Disc too long

    TOCError: Disc too long

    I can't seem to rip any CD on my drive: whipper fails after generating the TOC with discid.disc.TOCError: Disc too long.

    The command was invoked like so:

    whipper cd -d /dev/cdrom rip --track-template '%t - %n.%x' --disc-template '%A - %D.%x' --cdr -O out
    
    The full log from whipper itself
    CDDB disc id: 8d0fcd0a
    MusicBrainz disc id 6I3QCfDWRuMiHW1doZlI.DOiLnM-
    MusicBrainz lookup URL https://musicbrainz.org/cdtoc/attach?toc=1+10+303687+300+26607+57615+84627+116687+145361+170311+199940+229569+266544&tracks=10&id=6I3QCfDWRuMiHW1doZlI.DOiLnM-
    Disc duration: 01:07:25.160, 10 audio tracks
    
    Matching releases:
    
    Artist  : 荒御霊
    Title   : Life Beyond Death
    Duration: 01:07:25.158
    URL     : https://musicbrainz.org/release/8fdcf8ab-4a4b-4178-9b7e-d22e6062dadd
    Release : 8fdcf8ab-4a4b-4178-9b7e-d22e6062dadd
    Type    : Album
    Country : Japan
    Cat no  : 0054
    
    Track 1 finished, found 8702 Q sub-channels with CRC errors
    Track 2 finished, found 10152 Q sub-channels with CRC errors
    Track 3 finished, found 8967 Q sub-channels with CRC errors
    Track 4 finished, found 10956 Q sub-channels with CRC errors
    Track 5 finished, found 9370 Q sub-channels with CRC errors
    Track 6 finished, found 8289 Q sub-channels with CRC errors
    Track 7 finished, found 9802 Q sub-channels with CRC errors
    Track 8 finished, found 10296 Q sub-channels with CRC errors
    Track 10 finished, found 12092 Q sub-channels with CRC errors
    Traceback (most recent call last):
      File "/usr/bin/whipper", line 33, in <module>
        sys.exit(load_entry_point('whipper==0.10.0', 'console_scripts', 'whipper')())
      File "/usr/lib64/python3.10/site-packages/whipper/command/main.py", line 56, in main
        ret = cmd.do()
      File "/usr/lib64/python3.10/site-packages/whipper/command/basecommand.py", line 141, in do
        return self.cmd.do()
      File "/usr/lib64/python3.10/site-packages/whipper/command/basecommand.py", line 141, in do
        return self.cmd.do()
      File "/usr/lib64/python3.10/site-packages/whipper/command/cd.py", line 163, in do
        self.itable = self.program.getTable(self.runner,
      File "/usr/lib64/python3.10/site-packages/whipper/common/program.py", line 136, in getTable
        itable.getMusicBrainzDiscId())
      File "/usr/lib64/python3.10/site-packages/whipper/image/table.py", line 372, in getMusicBrainzDiscId
        disc = put(values[0], values[1], values[2], values[3:])
      File "/usr/lib/python3.10/site-packages/discid/disc.py", line 76, in put
        disc.put(first, last, disc_sectors, track_offsets)
      File "/usr/lib/python3.10/site-packages/discid/disc.py", line 176, in put
        raise TOCError(self._get_error_msg())
    discid.disc.TOCError: Disc too long
    
    The debug log
    DEBUG:musicbrainzngs:set user-agent to whipper/0.10.0 python-musicbrainzngs/0.7.1 ( https://github.com/whipper-team/whipper )
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:looking at section 'drive:PLDS%20%20%20%20%3ADVD-RW%20DS8A8SH%20%20%3AKU54'
    DEBUG:whipper.common.config:vendor: 'PLDS    ' versus 'PLDS'
    DEBUG:whipper.common.config:model: 'DVD-RW DS8A8SH  ' versus 'DVD-RW DS8A8SH'
    DEBUG:whipper.common.config:release: 'KU54' versus 'KU54'
    INFO:whipper.command.cd:using configured read offset 6
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.common.config:loaded 2 sections from config file
    INFO:whipper.command.cd:checking device /dev/sr0
    DEBUG:whipper.program.utils:loading (eject -t) device /dev/sr0
    WARNING:whipper.program.utils:command 'eject -t /dev/sr0' returned with exit code '1' (b'eject: CD-ROM tray close command failed: No such file or directory')
    DEBUG:whipper.program.utils:possibly unmount real path '/dev/sr0'
    DEBUG:whipper.extern.task.task:run task <whipper.program.cdrdao.ReadTOCTask object at 0x7ff709c2e260>
    DEBUG:whipper.extern.task.task:Adding listener <whipper.common.task.SyncRunner object at 0x7ff709c2f9d0>
    DEBUG:whipper.extern.task.task:run loop
    DEBUG:whipper.extern.task.task:start task <whipper.program.cdrdao.ReadTOCTask object at 0x7ff709c2e260>
    DEBUG:whipper.extern.task.task:starting
    DEBUG:whipper.extern.task.task:notifying progress: 0.0 on 'Reading TOC'
    DEBUG:whipper.program.cdrdao:RE: Begin cdrdao toc-read
    DEBUG:whipper.program.cdrdao:RE: Reached leadout
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 1
    DEBUG:whipper.extern.task.task:notifying progress: 0.1 on 'Reading TOC'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 2
    DEBUG:whipper.extern.task.task:notifying progress: 0.2 on 'Reading TOC'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 3
    DEBUG:whipper.extern.task.task:notifying progress: 0.3 on 'Reading TOC'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 4
    DEBUG:whipper.extern.task.task:notifying progress: 0.4 on 'Reading TOC'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 5
    DEBUG:whipper.extern.task.task:notifying progress: 0.5 on 'Reading TOC'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 6
    DEBUG:whipper.extern.task.task:notifying progress: 0.6 on 'Reading TOC'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 7
    DEBUG:whipper.extern.task.task:notifying progress: 0.7 on 'Reading TOC'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 8
    DEBUG:whipper.extern.task.task:notifying progress: 0.8 on 'Reading TOC'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 9
    DEBUG:whipper.extern.task.task:notifying progress: 0.9 on 'Reading TOC'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 10
    DEBUG:whipper.extern.task.task:notifying progress: 1.0 on 'Reading TOC'
    DEBUG:whipper.image.table:set logName
    DEBUG:whipper.image.toc:found track 1, mode AUDIO, at absoluteOffset 0
    DEBUG:whipper.image.toc:found ISRC code 000000000000
    DEBUG:whipper.image.toc:silence of '00:02:00'
    DEBUG:whipper.image.toc:appending source, counter 0, abs offset 0, source None
    DEBUG:whipper.image.toc:file data.wav, start 0, length 26307
    DEBUG:whipper.image.toc:track 1, switched to new file, increased counter to 1
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 150, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 0, we are in source None
    DEBUG:whipper.image.toc:[track 01 index 00] added <Index 00 absolute 0 path None relative 0 counter 0>
    DEBUG:whipper.image.toc:at abs offset 150, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 01 index 01] trackOffset 150, added <Index 01 absolute 150 path 'data.wav' relative 0 counter 1>
    DEBUG:whipper.image.toc:found track 2, mode AUDIO, at absoluteOffset 26457
    DEBUG:whipper.image.toc:found ISRC code 000000000000
    DEBUG:whipper.image.toc:file data.wav, start 26307, length 31008
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 26457, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 26457, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 02 index 01] trackOffset 0, added <Index 01 absolute 26457 path 'data.wav' relative 26307 counter 1>
    DEBUG:whipper.image.toc:found track 3, mode AUDIO, at absoluteOffset 57465
    DEBUG:whipper.image.toc:found ISRC code 000000000000
    DEBUG:whipper.image.toc:file data.wav, start 57315, length 27012
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 57465, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 57465, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 03 index 01] trackOffset 0, added <Index 01 absolute 57465 path 'data.wav' relative 57315 counter 1>
    DEBUG:whipper.image.toc:found track 4, mode AUDIO, at absoluteOffset 84477
    DEBUG:whipper.image.toc:found ISRC code 000000000000
    DEBUG:whipper.image.toc:file data.wav, start 84327, length 32060
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 84477, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 84477, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 04 index 01] trackOffset 0, added <Index 01 absolute 84477 path 'data.wav' relative 84327 counter 1>
    DEBUG:whipper.image.toc:found track 5, mode AUDIO, at absoluteOffset 116537
    DEBUG:whipper.image.toc:found ISRC code 000000000000
    DEBUG:whipper.image.toc:file data.wav, start 116387, length 28674
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 116537, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 116537, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 05 index 01] trackOffset 0, added <Index 01 absolute 116537 path 'data.wav' relative 116387 counter 1>
    DEBUG:whipper.image.toc:found track 6, mode AUDIO, at absoluteOffset 145211
    DEBUG:whipper.image.toc:found ISRC code 000000000000
    DEBUG:whipper.image.toc:file data.wav, start 145061, length 24950
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 145211, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 145211, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 06 index 01] trackOffset 0, added <Index 01 absolute 145211 path 'data.wav' relative 145061 counter 1>
    DEBUG:whipper.image.toc:found track 7, mode AUDIO, at absoluteOffset 170161
    DEBUG:whipper.image.toc:found ISRC code 000000000000
    DEBUG:whipper.image.toc:file data.wav, start 170011, length 29629
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 170161, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 170161, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 07 index 01] trackOffset 0, added <Index 01 absolute 170161 path 'data.wav' relative 170011 counter 1>
    DEBUG:whipper.image.toc:found track 8, mode AUDIO, at absoluteOffset 199790
    DEBUG:whipper.image.toc:found ISRC code 000000000000
    DEBUG:whipper.image.toc:file data.wav, start 199640, length 29629
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 199790, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 199790, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 08 index 01] trackOffset 0, added <Index 01 absolute 199790 path 'data.wav' relative 199640 counter 1>
    DEBUG:whipper.image.toc:found track 9, mode AUDIO, at absoluteOffset 229419
    DEBUG:whipper.image.toc:found ISRC code 000000000000
    DEBUG:whipper.image.toc:file data.wav, start 229269, length 36975
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 229419, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 229419, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 09 index 01] trackOffset 0, added <Index 01 absolute 229419 path 'data.wav' relative 229269 counter 1>
    DEBUG:whipper.image.toc:found track 10, mode AUDIO, at absoluteOffset 266394
    DEBUG:whipper.image.toc:found ISRC code 000000000000
    DEBUG:whipper.image.toc:file data.wav, start 266244, length 37143
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 266394, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 266394, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 10 index 01] trackOffset 0, added <Index 01 absolute 266394 path 'data.wav' relative 266244 counter 1>
    DEBUG:whipper.image.toc:parse: leadout: 303537
    DEBUG:whipper.extern.task.task:stopping
    DEBUG:whipper.extern.task.task:reset runner to None
    DEBUG:whipper.extern.task.task:stopped task <whipper.program.cdrdao.ReadTOCTask object at 0x7ff709c2e260>
    DEBUG:whipper.extern.task.task:done running task <whipper.program.cdrdao.ReadTOCTask object at 0x7ff709c2e260>
    DEBUG:whipper.image.table:leadout LBA: 303537
    DEBUG:whipper.image.table:cddb values: DiscID(offsets=[300, 26607, 57615, 84627, 116687, 145361, 170311, 199940, 229569, 266544], total_length=4045, track_count=10, playable_length=4047)
    DEBUG:whipper.image.table:cddb disc id debug: 8d0fcd0a 10 300 26607 57615 84627 116687 145361 170311 199940 229569 266544 4049
    DEBUG:whipper.image.table:MusicBrainz values: [1, 10, 303687, 300, 26607, 57615, 84627, 116687, 145361, 170311, 199940, 229569, 266544]
    DEBUG:whipper.image.table:getMusicBrainzDiscId: returning '6I3QCfDWRuMiHW1doZlI.DOiLnM-'
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.image.table:getMusicBrainzDiscId: returning cached '6I3QCfDWRuMiHW1doZlI.DOiLnM-'
    DEBUG:whipper.image.table:MusicBrainz values: [1, 10, 303687, 300, 26607, 57615, 84627, 116687, 145361, 170311, 199940, 229569, 266544]
    DEBUG:whipper.image.table:leadout LBA: 303537
    DEBUG:whipper.common.config:loaded 2 sections from config file
    DEBUG:whipper.image.table:getMusicBrainzDiscId: returning cached '6I3QCfDWRuMiHW1doZlI.DOiLnM-'
    DEBUG:whipper.image.table:MusicBrainz values: [1, 10, 303687, 300, 26607, 57615, 84627, 116687, 145361, 170311, 199940, 229569, 266544]
    DEBUG:whipper.common.program:MusicBrainz submit url: 'https://musicbrainz.org/cdtoc/attach?toc=1+10+303687+300+26607+57615+84627+116687+145361+170311+199940+229569+266544&tracks=10&id=6I3QCfDWRuMiHW1doZlI.DOiLnM-'
    DEBUG:whipper.common.mbngs:looking up results for discid '6I3QCfDWRuMiHW1doZlI.DOiLnM-'
    DEBUG:whipper.common.mbngs:found 1 releases for discid '6I3QCfDWRuMiHW1doZlI.DOiLnM-'
    DEBUG:whipper.common.mbngs:result {
        "id": "8fdcf8ab-4a4b-4178-9b7e-d22e6062dadd",
        "title": "Life Beyond Death",
        "status": "Official",
        "quality": "normal",
        "packaging": "Keep Case",
        "artist-credit": [
            {
                "artist": {
                    "id": "171a504f-d393-4272-ac67-29040717df7b",
                    "type": "Group",
                    "name": "\u8352\u5fa1\u970a",
                    "sort-name": "AramiTama"
                }
            }
        ],
        "release-group": {
            "id": "e0f795ce-8e06-4f71-8a90-f95622d1a9ae",
            "type": "Album",
            "title": "Life Beyond Death",
            "first-release-date": "2022-08-14",
            "primary-type": "Album"
        },
        "date": "2022-08-14",
        "country": "JP",
        "release-event-list": [
            {
                "date": "2022-08-14",
                "area": {
                    "id": "2db42837-c832-3c27-b4a3-08198f75693c",
                    "name": "Japan",
                    "sort-name": "Japan",
                    "iso-3166-1-code-list": [
                        "JP"
                    ]
                }
            }
        ],
        "release-event-count": 1,
        "barcode": "",
        "cover-art-archive": {
            "artwork": "true",
            "count": "1",
            "front": "true",
            "back": "false"
        },
        "medium-list": [
            {
                "position": "1",
                "format": "CD-R",
                "disc-list": [
                    {
                        "id": "6I3QCfDWRuMiHW1doZlI.DOiLnM-",
                        "sectors": "303687",
                        "offset-list": [
                            300,
                            26607,
                            57615,
                            84627,
                            116687,
                            145361,
                            170311,
                            199940,
                            229569,
                            266544
                        ],
                        "offset-count": 10
                    }
                ],
                "disc-count": 1,
                "track-list": [
                    {
                        "id": "aeef5ffc-d2bf-4417-aaff-6d75360cd8a3",
                        "position": "1",
                        "number": "1",
                        "length": "350760",
                        "recording": {
                            "id": "8917be9b-0741-4c47-b574-9454edb4d390",
                            "title": "Selflessness",
                            "length": "350760"
                        },
                        "track_or_recording_length": "350760"
                    },
                    {
                        "id": "d215006b-db0a-4eea-a1cc-59a44c5ffaa6",
                        "position": "2",
                        "number": "2",
                        "length": "413440",
                        "recording": {
                            "id": "6ff96dac-2a2c-48ec-9b29-cc4f802fc202",
                            "title": "Untold Folklore",
                            "length": "413440"
                        },
                        "track_or_recording_length": "413440"
                    },
                    {
                        "id": "77f1f88d-d961-4a6d-8b90-9fccc7194c3b",
                        "position": "3",
                        "number": "3",
                        "length": "360160",
                        "recording": {
                            "id": "5b038576-9ba7-4134-98bc-99ed402facfc",
                            "title": "Nothingness Utopia",
                            "length": "360160"
                        },
                        "track_or_recording_length": "360160"
                    },
                    {
                        "id": "9a5d6598-c48f-4ceb-8e1d-8aba3b4adfa3",
                        "position": "4",
                        "number": "4",
                        "length": "427466",
                        "recording": {
                            "id": "709c7793-a6be-4723-a5cb-17da3d1d7ca7",
                            "title": "Roguelike",
                            "length": "427466"
                        },
                        "track_or_recording_length": "427466"
                    },
                    {
                        "id": "9f8e1d81-3720-483c-8c6e-dea178f0788a",
                        "position": "5",
                        "number": "5",
                        "length": "382320",
                        "recording": {
                            "id": "cf833135-e4ad-4bef-9f84-371bf0c4f8ce",
                            "title": "Unnatural Nature",
                            "length": "382320"
                        },
                        "track_or_recording_length": "382320"
                    },
                    {
                        "id": "e70174a0-8211-409b-ae84-487604c3691d",
                        "position": "6",
                        "number": "6",
                        "length": "332666",
                        "recording": {
                            "id": "e5c0ec00-8a00-4aca-90cb-ed08e7c38b38",
                            "title": "Predawn",
                            "length": "332666"
                        },
                        "track_or_recording_length": "332666"
                    },
                    {
                        "id": "cbf8f26d-3d86-4aa6-8c0f-f0841cafd765",
                        "position": "7",
                        "number": "7",
                        "length": "395053",
                        "recording": {
                            "id": "f805dd56-37d0-46aa-b8a1-483769c5aa6c",
                            "title": "Game of Death",
                            "length": "395053"
                        },
                        "track_or_recording_length": "395053"
                    },
                    {
                        "id": "84508593-f145-4047-8987-2522a9cdcff3",
                        "position": "8",
                        "number": "8",
                        "length": "395053",
                        "recording": {
                            "id": "fa7ddd09-d881-48b8-a5ba-7a052aafdc0d",
                            "title": "Engine",
                            "length": "395053"
                        },
                        "track_or_recording_length": "395053"
                    },
                    {
                        "id": "ea884c88-b231-4719-834d-a9f534ec3ea9",
                        "position": "9",
                        "number": "9",
                        "length": "493000",
                        "recording": {
                            "id": "6763a7b0-9c2c-4efa-9e30-d5d367f1ebed",
                            "title": "Immortal Life after Death",
                            "length": "493000"
                        },
                        "track_or_recording_length": "493000"
                    },
                    {
                        "id": "7fc1f4fe-3faf-4f45-abb6-59543172a912",
                        "position": "10",
                        "number": "10",
                        "length": "495240",
                        "recording": {
                            "id": "2e4048b8-cc6d-4d2c-bb1a-60c939cad46a",
                            "title": "Hirokawa",
                            "length": "495240"
                        },
                        "track_or_recording_length": "495240"
                    }
                ],
                "track-count": 10
            }
        ],
        "medium-count": 1,
        "artist-credit-phrase": "\u8352\u5fa1\u970a"
    }: artist '荒御霊', title 'Life Beyond Death'
    DEBUG:whipper.common.mbngs:release {
        "id": "8fdcf8ab-4a4b-4178-9b7e-d22e6062dadd",
        "title": "Life Beyond Death",
        "status": "Official",
        "quality": "normal",
        "packaging": "Keep Case",
        "artist-credit": [
            {
                "artist": {
                    "id": "171a504f-d393-4272-ac67-29040717df7b",
                    "type": "Group",
                    "name": "\u8352\u5fa1\u970a",
                    "sort-name": "AramiTama"
                }
            }
        ],
        "release-group": {
            "id": "e0f795ce-8e06-4f71-8a90-f95622d1a9ae",
            "type": "Album",
            "title": "Life Beyond Death",
            "first-release-date": "2022-08-14",
            "primary-type": "Album",
            "artist-credit": [
                {
                    "artist": {
                        "id": "171a504f-d393-4272-ac67-29040717df7b",
                        "type": "Group",
                        "name": "\u8352\u5fa1\u970a",
                        "sort-name": "AramiTama"
                    }
                }
            ],
            "artist-credit-phrase": "\u8352\u5fa1\u970a"
        },
        "date": "2022-08-14",
        "country": "JP",
        "release-event-list": [
            {
                "date": "2022-08-14",
                "area": {
                    "id": "2db42837-c832-3c27-b4a3-08198f75693c",
                    "name": "Japan",
                    "sort-name": "Japan",
                    "iso-3166-1-code-list": [
                        "JP"
                    ]
                }
            }
        ],
        "release-event-count": 1,
        "barcode": "",
        "cover-art-archive": {
            "artwork": "true",
            "count": "1",
            "front": "true",
            "back": "false"
        },
        "label-info-list": [
            {
                "catalog-number": "0054",
                "label": {
                    "id": "8e40b82c-24ca-46cb-b1f8-76fc6d7ebcdd",
                    "type": "Original Production",
                    "name": "\u8352\u5fa1\u970a",
                    "sort-name": "\u8352\u5fa1\u970a",
                    "disambiguation": "d\u014djin circle"
                }
            }
        ],
        "label-info-count": 1,
        "medium-list": [
            {
                "position": "1",
                "format": "CD-R",
                "disc-list": [
                    {
                        "id": "6I3QCfDWRuMiHW1doZlI.DOiLnM-",
                        "sectors": "303687",
                        "offset-list": [
                            300,
                            26607,
                            57615,
                            84627,
                            116687,
                            145361,
                            170311,
                            199940,
                            229569,
                            266544
                        ],
                        "offset-count": 10
                    }
                ],
                "disc-count": 1,
                "track-list": [
                    {
                        "id": "aeef5ffc-d2bf-4417-aaff-6d75360cd8a3",
                        "position": "1",
                        "number": "1",
                        "length": "350760",
                        "recording": {
                            "id": "8917be9b-0741-4c47-b574-9454edb4d390",
                            "title": "Selflessness",
                            "length": "350760",
                            "artist-credit": [
                                {
                                    "artist": {
                                        "id": "171a504f-d393-4272-ac67-29040717df7b",
                                        "type": "Group",
                                        "name": "\u8352\u5fa1\u970a",
                                        "sort-name": "AramiTama"
                                    }
                                }
                            ],
                            "artist-credit-phrase": "\u8352\u5fa1\u970a"
                        },
                        "artist-credit": [
                            {
                                "artist": {
                                    "id": "171a504f-d393-4272-ac67-29040717df7b",
                                    "type": "Group",
                                    "name": "\u8352\u5fa1\u970a",
                                    "sort-name": "AramiTama"
                                }
                            }
                        ],
                        "artist-credit-phrase": "\u8352\u5fa1\u970a",
                        "track_or_recording_length": "350760"
                    },
                    {
                        "id": "d215006b-db0a-4eea-a1cc-59a44c5ffaa6",
                        "position": "2",
                        "number": "2",
                        "length": "413440",
                        "recording": {
                            "id": "6ff96dac-2a2c-48ec-9b29-cc4f802fc202",
                            "title": "Untold Folklore",
                            "length": "413440",
                            "artist-credit": [
                                {
                                    "artist": {
                                        "id": "171a504f-d393-4272-ac67-29040717df7b",
                                        "type": "Group",
                                        "name": "\u8352\u5fa1\u970a",
                                        "sort-name": "AramiTama"
                                    }
                                }
                            ],
                            "artist-credit-phrase": "\u8352\u5fa1\u970a"
                        },
                        "artist-credit": [
                            {
                                "artist": {
                                    "id": "171a504f-d393-4272-ac67-29040717df7b",
                                    "type": "Group",
                                    "name": "\u8352\u5fa1\u970a",
                                    "sort-name": "AramiTama"
                                }
                            }
                        ],
                        "artist-credit-phrase": "\u8352\u5fa1\u970a",
                        "track_or_recording_length": "413440"
                    },
                    {
                        "id": "77f1f88d-d961-4a6d-8b90-9fccc7194c3b",
                        "position": "3",
                        "number": "3",
                        "length": "360160",
                        "recording": {
                            "id": "5b038576-9ba7-4134-98bc-99ed402facfc",
                            "title": "Nothingness Utopia",
                            "length": "360160",
                            "artist-credit": [
                                {
                                    "artist": {
                                        "id": "171a504f-d393-4272-ac67-29040717df7b",
                                        "type": "Group",
                                        "name": "\u8352\u5fa1\u970a",
                                        "sort-name": "AramiTama"
                                    }
                                }
                            ],
                            "artist-credit-phrase": "\u8352\u5fa1\u970a"
                        },
                        "artist-credit": [
                            {
                                "artist": {
                                    "id": "171a504f-d393-4272-ac67-29040717df7b",
                                    "type": "Group",
                                    "name": "\u8352\u5fa1\u970a",
                                    "sort-name": "AramiTama"
                                }
                            }
                        ],
                        "artist-credit-phrase": "\u8352\u5fa1\u970a",
                        "track_or_recording_length": "360160"
                    },
                    {
                        "id": "9a5d6598-c48f-4ceb-8e1d-8aba3b4adfa3",
                        "position": "4",
                        "number": "4",
                        "length": "427466",
                        "recording": {
                            "id": "709c7793-a6be-4723-a5cb-17da3d1d7ca7",
                            "title": "Roguelike",
                            "length": "427466",
                            "artist-credit": [
                                {
                                    "artist": {
                                        "id": "171a504f-d393-4272-ac67-29040717df7b",
                                        "type": "Group",
                                        "name": "\u8352\u5fa1\u970a",
                                        "sort-name": "AramiTama"
                                    }
                                }
                            ],
                            "artist-credit-phrase": "\u8352\u5fa1\u970a"
                        },
                        "artist-credit": [
                            {
                                "artist": {
                                    "id": "171a504f-d393-4272-ac67-29040717df7b",
                                    "type": "Group",
                                    "name": "\u8352\u5fa1\u970a",
                                    "sort-name": "AramiTama"
                                }
                            }
                        ],
                        "artist-credit-phrase": "\u8352\u5fa1\u970a",
                        "track_or_recording_length": "427466"
                    },
                    {
                        "id": "9f8e1d81-3720-483c-8c6e-dea178f0788a",
                        "position": "5",
                        "number": "5",
                        "length": "382320",
                        "recording": {
                            "id": "cf833135-e4ad-4bef-9f84-371bf0c4f8ce",
                            "title": "Unnatural Nature",
                            "length": "382320",
                            "artist-credit": [
                                {
                                    "artist": {
                                        "id": "171a504f-d393-4272-ac67-29040717df7b",
                                        "type": "Group",
                                        "name": "\u8352\u5fa1\u970a",
                                        "sort-name": "AramiTama"
                                    }
                                }
                            ],
                            "artist-credit-phrase": "\u8352\u5fa1\u970a"
                        },
                        "artist-credit": [
                            {
                                "artist": {
                                    "id": "171a504f-d393-4272-ac67-29040717df7b",
                                    "type": "Group",
                                    "name": "\u8352\u5fa1\u970a",
                                    "sort-name": "AramiTama"
                                }
                            }
                        ],
                        "artist-credit-phrase": "\u8352\u5fa1\u970a",
                        "track_or_recording_length": "382320"
                    },
                    {
                        "id": "e70174a0-8211-409b-ae84-487604c3691d",
                        "position": "6",
                        "number": "6",
                        "length": "332666",
                        "recording": {
                            "id": "e5c0ec00-8a00-4aca-90cb-ed08e7c38b38",
                            "title": "Predawn",
                            "length": "332666",
                            "artist-credit": [
                                {
                                    "artist": {
                                        "id": "171a504f-d393-4272-ac67-29040717df7b",
                                        "type": "Group",
                                        "name": "\u8352\u5fa1\u970a",
                                        "sort-name": "AramiTama"
                                    }
                                }
                            ],
                            "artist-credit-phrase": "\u8352\u5fa1\u970a"
                        },
                        "artist-credit": [
                            {
                                "artist": {
                                    "id": "171a504f-d393-4272-ac67-29040717df7b",
                                    "type": "Group",
                                    "name": "\u8352\u5fa1\u970a",
                                    "sort-name": "AramiTama"
                                }
                            }
                        ],
                        "artist-credit-phrase": "\u8352\u5fa1\u970a",
                        "track_or_recording_length": "332666"
                    },
                    {
                        "id": "cbf8f26d-3d86-4aa6-8c0f-f0841cafd765",
                        "position": "7",
                        "number": "7",
                        "length": "395053",
                        "recording": {
                            "id": "f805dd56-37d0-46aa-b8a1-483769c5aa6c",
                            "title": "Game of Death",
                            "length": "395053",
                            "artist-credit": [
                                {
                                    "artist": {
                                        "id": "171a504f-d393-4272-ac67-29040717df7b",
                                        "type": "Group",
                                        "name": "\u8352\u5fa1\u970a",
                                        "sort-name": "AramiTama"
                                    }
                                }
                            ],
                            "artist-credit-phrase": "\u8352\u5fa1\u970a"
                        },
                        "artist-credit": [
                            {
                                "artist": {
                                    "id": "171a504f-d393-4272-ac67-29040717df7b",
                                    "type": "Group",
                                    "name": "\u8352\u5fa1\u970a",
                                    "sort-name": "AramiTama"
                                }
                            }
                        ],
                        "artist-credit-phrase": "\u8352\u5fa1\u970a",
                        "track_or_recording_length": "395053"
                    },
                    {
                        "id": "84508593-f145-4047-8987-2522a9cdcff3",
                        "position": "8",
                        "number": "8",
                        "length": "395053",
                        "recording": {
                            "id": "fa7ddd09-d881-48b8-a5ba-7a052aafdc0d",
                            "title": "Engine",
                            "length": "395053",
                            "artist-credit": [
                                {
                                    "artist": {
                                        "id": "171a504f-d393-4272-ac67-29040717df7b",
                                        "type": "Group",
                                        "name": "\u8352\u5fa1\u970a",
                                        "sort-name": "AramiTama"
                                    }
                                }
                            ],
                            "artist-credit-phrase": "\u8352\u5fa1\u970a"
                        },
                        "artist-credit": [
                            {
                                "artist": {
                                    "id": "171a504f-d393-4272-ac67-29040717df7b",
                                    "type": "Group",
                                    "name": "\u8352\u5fa1\u970a",
                                    "sort-name": "AramiTama"
                                }
                            }
                        ],
                        "artist-credit-phrase": "\u8352\u5fa1\u970a",
                        "track_or_recording_length": "395053"
                    },
                    {
                        "id": "ea884c88-b231-4719-834d-a9f534ec3ea9",
                        "position": "9",
                        "number": "9",
                        "length": "493000",
                        "recording": {
                            "id": "6763a7b0-9c2c-4efa-9e30-d5d367f1ebed",
                            "title": "Immortal Life after Death",
                            "length": "493000",
                            "artist-credit": [
                                {
                                    "artist": {
                                        "id": "171a504f-d393-4272-ac67-29040717df7b",
                                        "type": "Group",
                                        "name": "\u8352\u5fa1\u970a",
                                        "sort-name": "AramiTama"
                                    }
                                }
                            ],
                            "artist-credit-phrase": "\u8352\u5fa1\u970a"
                        },
                        "artist-credit": [
                            {
                                "artist": {
                                    "id": "171a504f-d393-4272-ac67-29040717df7b",
                                    "type": "Group",
                                    "name": "\u8352\u5fa1\u970a",
                                    "sort-name": "AramiTama"
                                }
                            }
                        ],
                        "artist-credit-phrase": "\u8352\u5fa1\u970a",
                        "track_or_recording_length": "493000"
                    },
                    {
                        "id": "7fc1f4fe-3faf-4f45-abb6-59543172a912",
                        "position": "10",
                        "number": "10",
                        "length": "495240",
                        "recording": {
                            "id": "2e4048b8-cc6d-4d2c-bb1a-60c939cad46a",
                            "title": "Hirokawa",
                            "length": "495240",
                            "artist-credit": [
                                {
                                    "artist": {
                                        "id": "171a504f-d393-4272-ac67-29040717df7b",
                                        "type": "Group",
                                        "name": "\u8352\u5fa1\u970a",
                                        "sort-name": "AramiTama"
                                    }
                                }
                            ],
                            "artist-credit-phrase": "\u8352\u5fa1\u970a"
                        },
                        "artist-credit": [
                            {
                                "artist": {
                                    "id": "171a504f-d393-4272-ac67-29040717df7b",
                                    "type": "Group",
                                    "name": "\u8352\u5fa1\u970a",
                                    "sort-name": "AramiTama"
                                }
                            }
                        ],
                        "artist-credit-phrase": "\u8352\u5fa1\u970a",
                        "track_or_recording_length": "495240"
                    }
                ],
                "track-count": 10
            }
        ],
        "medium-count": 1,
        "artist-credit-phrase": "\u8352\u5fa1\u970a"
    }
    DEBUG:whipper.common.mbngs:getMetadata for release id '8fdcf8ab-4a4b-4178-9b7e-d22e6062dadd'
    DEBUG:whipper.common.mbngs:duration 4045158
    DEBUG:whipper.image.table:leadout LBA: 303537
    DEBUG:whipper.program.cdrdao:executing ['cdrdao', 'disk-info', '-v1', '--device', '/dev/sr0']
    DEBUG:whipper.image.table:leadout LBA: 303537
    DEBUG:whipper.image.table:cddb values: DiscID(offsets=[300, 26607, 57615, 84627, 116687, 145361, 170311, 199940, 229569, 266544], total_length=4045, track_count=10, playable_length=4047)
    DEBUG:whipper.image.table:cddb disc id debug: 8d0fcd0a 10 300 26607 57615 84627 116687 145361 170311 199940 229569 266544 4049
    DEBUG:whipper.image.table:getMusicBrainzDiscId: returning cached '6I3QCfDWRuMiHW1doZlI.DOiLnM-'
    DEBUG:whipper.extern.task.task:run task <whipper.program.cdrdao.ReadTOCTask object at 0x7ff70bf8c1c0>
    DEBUG:whipper.extern.task.task:Adding listener <whipper.common.task.SyncRunner object at 0x7ff709c2f9d0>
    DEBUG:whipper.extern.task.task:run loop
    DEBUG:whipper.extern.task.task:start task <whipper.program.cdrdao.ReadTOCTask object at 0x7ff70bf8c1c0>
    DEBUG:whipper.extern.task.task:starting
    DEBUG:whipper.extern.task.task:notifying progress: 0.0 on 'Reading table'
    DEBUG:whipper.program.cdrdao:RE: Begin cdrdao toc-read
    DEBUG:whipper.program.cdrdao:RE: Reached leadout
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 1
    DEBUG:whipper.extern.task.task:notifying progress: 0.1 on 'Reading table'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 2
    DEBUG:whipper.extern.task.task:notifying progress: 0.2 on 'Reading table'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 3
    DEBUG:whipper.extern.task.task:notifying progress: 0.3 on 'Reading table'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 4
    DEBUG:whipper.extern.task.task:notifying progress: 0.4 on 'Reading table'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 5
    DEBUG:whipper.extern.task.task:notifying progress: 0.5 on 'Reading table'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 6
    DEBUG:whipper.extern.task.task:notifying progress: 0.6 on 'Reading table'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 7
    DEBUG:whipper.extern.task.task:notifying progress: 0.7 on 'Reading table'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 8
    DEBUG:whipper.extern.task.task:notifying progress: 0.8 on 'Reading table'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 9
    DEBUG:whipper.extern.task.task:notifying progress: 0.9 on 'Reading table'
    DEBUG:whipper.program.cdrdao:RE: Began reading track: 10
    DEBUG:whipper.extern.task.task:notifying progress: 1.0 on 'Reading table'
    DEBUG:whipper.image.table:set logName
    DEBUG:whipper.image.toc:found track 1, mode AUDIO, at absoluteOffset 0
    DEBUG:whipper.image.toc:found ISRC code 000000000000
    DEBUG:whipper.image.toc:silence of '00:02:00'
    DEBUG:whipper.image.toc:appending source, counter 0, abs offset 0, source None
    DEBUG:whipper.image.toc:file data.wav, start 0, length 26307
    DEBUG:whipper.image.toc:track 1, switched to new file, increased counter to 1
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 150, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 0, we are in source None
    DEBUG:whipper.image.toc:[track 01 index 00] added <Index 00 absolute 0 path None relative 0 counter 0>
    DEBUG:whipper.image.toc:at abs offset 150, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 01 index 01] trackOffset 150, added <Index 01 absolute 150 path 'data.wav' relative 0 counter 1>
    DEBUG:whipper.image.toc:found track 2, mode AUDIO, at absoluteOffset 26457
    DEBUG:whipper.image.toc:found ISRC code 800000000000
    DEBUG:whipper.image.toc:file data.wav, start 26307, length 31008
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 26457, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 26457, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 02 index 01] trackOffset 0, added <Index 01 absolute 26457 path 'data.wav' relative 26307 counter 1>
    DEBUG:whipper.image.toc:found track 3, mode AUDIO, at absoluteOffset 57465
    DEBUG:whipper.image.toc:found ISRC code L00000000000
    DEBUG:whipper.image.toc:file data.wav, start 57315, length 27012
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 57465, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 57465, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 03 index 01] trackOffset 0, added <Index 01 absolute 57465 path 'data.wav' relative 57315 counter 1>
    DEBUG:whipper.image.toc:found track 4, mode AUDIO, at absoluteOffset 84477
    DEBUG:whipper.image.toc:found ISRC code H00000000000
    DEBUG:whipper.image.toc:file data.wav, start 84327, length 32060
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 84477, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 84477, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 04 index 01] trackOffset 0, added <Index 01 absolute 84477 path 'data.wav' relative 84327 counter 1>
    DEBUG:whipper.image.toc:found track 5, mode AUDIO, at absoluteOffset 116537
    DEBUG:whipper.image.toc:found ISRC code 400000000000
    DEBUG:whipper.image.toc:file data.wav, start 116387, length 28674
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 116537, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 116537, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 05 index 01] trackOffset 0, added <Index 01 absolute 116537 path 'data.wav' relative 116387 counter 1>
    DEBUG:whipper.image.toc:found track 6, mode AUDIO, at absoluteOffset 145211
    DEBUG:whipper.image.toc:found ISRC code D00000000000
    DEBUG:whipper.image.toc:file data.wav, start 145061, length 24950
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 145211, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 145211, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 06 index 01] trackOffset 0, added <Index 01 absolute 145211 path 'data.wav' relative 145061 counter 1>
    DEBUG:whipper.image.toc:found track 7, mode AUDIO, at absoluteOffset 170161
    DEBUG:whipper.image.toc:found ISRC code 000000000000
    DEBUG:whipper.image.toc:file data.wav, start 170011, length 29629
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 170161, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 170161, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 07 index 01] trackOffset 0, added <Index 01 absolute 170161 path 'data.wav' relative 170011 counter 1>
    DEBUG:whipper.image.toc:found track 8, mode AUDIO, at absoluteOffset 199790
    DEBUG:whipper.image.toc:found ISRC code 800000000000
    DEBUG:whipper.image.toc:file data.wav, start 199640, length 29629
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 199790, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 199790, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 08 index 01] trackOffset 0, added <Index 01 absolute 199790 path 'data.wav' relative 199640 counter 1>
    DEBUG:whipper.image.toc:found track 9, mode AUDIO, at absoluteOffset 229419
    DEBUG:whipper.image.toc:file data.wav, start 229269, length 0
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 229419, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 229419, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 09 index 01] trackOffset 0, added <Index 01 absolute 229419 path 'data.wav' relative 229269 counter 1>
    DEBUG:whipper.image.toc:found track 10, mode AUDIO, at absoluteOffset 229419
    DEBUG:whipper.image.toc:found ISRC code 800000000000
    DEBUG:whipper.image.toc:file data.wav, start 0, length 303687
    DEBUG:whipper.image.toc:appending source, counter 1, abs offset 229419, source <File 'data.wav'>
    DEBUG:whipper.image.toc:at abs offset 229419, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 10 index 00] added <Index 00 absolute 229419 path 'data.wav' relative 229269 counter 1>
    DEBUG:whipper.image.toc:at abs offset 495963, we are in source <File 'data.wav'>
    DEBUG:whipper.image.toc:[track 10 index 01] trackOffset 266544, added <Index 01 absolute 495963 path 'data.wav' relative 495813 counter 1>
    DEBUG:whipper.image.toc:parse: leadout: 533106
    DEBUG:whipper.program.cdrdao:[Errno 17] File exists: '/home/andry/Rips/AramiTama/Life Beyond Death/out'
    DEBUG:whipper.extern.task.task:stopping
    DEBUG:whipper.extern.task.task:reset runner to None
    DEBUG:whipper.extern.task.task:stopped task <whipper.program.cdrdao.ReadTOCTask object at 0x7ff70bf8c1c0>
    DEBUG:whipper.extern.task.task:done running task <whipper.program.cdrdao.ReadTOCTask object at 0x7ff70bf8c1c0>
    DEBUG:whipper.common.program:getTable: read table <whipper.image.table.Table object at 0x7ff709c268c0>
    DEBUG:whipper.image.table:MusicBrainz values: [1, 10, 533256, 300, 26607, 57615, 84627, 116687, 145361, 170311, 199940, 229569, 496113]
    

    Config file:

    [drive:PLDS%20%20%20%20%3ADVD-RW%20DS8A8SH%20%20%3AKU54]
    vendor = PLDS
    model = DVD-RW DS8A8SH
    release = KU54
    defeats_cache = True
    read_offset = 6
    
    [musicbrainz]
    server = https://musicbrainz.org
    

    Does anyone have any clue on what is happening here? Also 10000 Q sub-channels with CRC errors does not seem fine to me, but I may be wrong.

    Misc information

    • OS: Fedora 36 x86_64 (but this also happened under Void Linux)
    • Whipper version: 0.10
    • Drive: PLDS DVD-RW DS8A8SH (release KU54)
    • Configured read offset: 6
    • Can defeat audio cache: True

    Thank you for your time.

    opened by andry-dev 1
  • Rip of particular disc causes generation of corrupt .cue file and crash

    Rip of particular disc causes generation of corrupt .cue file and crash

    I've come across a particular disc, "Rush - Different Stages (Live)" disc 3, that causes whipper to generate a corrupt .cue file and crash.

    The problem seems to be related to the first track filename being saved to the .cue incorrectly, as when I manually corrected the first FILE line to reference the correct track 'Rush 03-01 - Bastille Day.flac, changed the .cue to readonly and changed the writeCue method in whipper/common/program.py to ignore if the .cue file is unwritable, the rip comand completed successfully.

    Here is the corrupt .cue file that is generated:

    REM DISCID 990EAC0B
    REM COMMENT "whipper 0.10.0"
    CATALOG 0075678312229
    FILE "../../../../../../data.wav" WAVE
      TRACK 01 AUDIO
        ISRC USAT27800028
        PREGAP 00:00:32
        INDEX 01 00:00:00
        INDEX 02 00:15:08
      TRACK 02 AUDIO
        ISRC USAT27800029
        INDEX 00 05:01:03
    FILE "./Rush 03-02 - By-Tor & The Snow Dog.flac" WAVE
        INDEX 01 00:00:00
    FILE "./Rush 03-03 - Xanadu.flac" WAVE
      TRACK 03 AUDIO
        ISRC USAT27800030
        INDEX 01 00:00:00
        INDEX 02 10:24:63
      TRACK 04 AUDIO
        ISRC USAT27800031
        INDEX 00 12:17:63
    FILE "./Rush 03-04 - Farewell to Kings.flac" WAVE
        INDEX 01 00:00:00
    FILE "./Rush 03-05 - Something for Nothing.flac" WAVE
      TRACK 05 AUDIO
        ISRC USAT27800032
        INDEX 01 00:00:00
    FILE "./Rush 03-06 - Cygnus X-1.flac" WAVE
      TRACK 06 AUDIO
        ISRC USAT27800033
        INDEX 01 00:00:00
    FILE "./Rush 03-07 - Anthem.flac" WAVE
      TRACK 07 AUDIO
        ISRC USAT27800034
        INDEX 01 00:00:00
      TRACK 08 AUDIO
        ISRC USAT27800035
        INDEX 00 04:39:05
    FILE "./Rush 03-08 - Working Man.flac" WAVE
        INDEX 01 00:00:00
    FILE "./Rush 03-09 - Fly by Night.flac" WAVE
      TRACK 09 AUDIO
        ISRC USAT27800036
        INDEX 01 00:00:00
    FILE "./Rush 03-10 - In the Mood.flac" WAVE
      TRACK 10 AUDIO
        ISRC USAT27800037
        INDEX 01 00:00:00
    FILE "./Rush 03-11 - Cinderella Man.flac" WAVE
      TRACK 11 AUDIO
        ISRC USAT27800038
        INDEX 01 00:00:00
    

    Here is the crash traceback (note that line numbers may not be accurate due to local unrelated fixes and improvements in my source tree (these have been submitted as PR's).

    Rip quality: 100.00%
    INFO:whipper.image.cue:parsing .cue file 'Rush - Different Stages Live (Disc 3 of 3)/Rush - Different Stages Live (Disc 3 of 3).cue'
    Traceback (most recent call last):
      File "/usr/bin/whipper", line 33, in <module>
        sys.exit(load_entry_point('whipper==0.10.0', 'console_scripts', 'whipper')())
      File "/usr/lib/python3/dist-packages/whipper/command/main.py", line 61, in main
        ret = cmd.do()
      File "/usr/lib/python3/dist-packages/whipper/command/basecommand.py", line 141, in do
        return self.cmd.do()
      File "/usr/lib/python3/dist-packages/whipper/command/basecommand.py", line 141, in do
        return self.cmd.do()
      File "/usr/lib/python3/dist-packages/whipper/command/cd.py", line 212, in do
        ret = self.doCommand()
      File "/usr/lib/python3/dist-packages/whipper/command/cd.py", line 617, in doCommand
        self.program.verifyImage(self.runner, self.itable)
      File "/usr/lib/python3/dist-packages/whipper/common/program.py", line 641, in verifyImage
        verifytask = image.ImageVerifyTask(cueImage)
      File "/usr/lib/python3/dist-packages/whipper/image/image.py", line 151, in __init__
        path = image.getRealPath(index.path)
      File "/usr/lib/python3/dist-packages/whipper/image/image.py", line 70, in getRealPath
        return self.cue.getRealPath(path)
      File "/usr/lib/python3/dist-packages/whipper/image/cue.py", line 188, in getRealPath
        return common.getRealPath(self._path, path)
      File "/usr/lib/python3/dist-packages/whipper/common/common.py", line 252, in getRealPath
        raise KeyError("Cannot find file for %r" % filePath)
    KeyError: "Cannot find file for '../../../../../../data.wav'"
    
    opened by eharris 0
  • offset find should allow specifying which track to test

    offset find should allow specifying which track to test

    It would be nice to be able to specify which track to perform offset testing on, as sometimes the first track might be damaged.

    Also, why is it necessary for every track to be successfully verified before whipper decides to use a particular offset? I often find that particular CD's, even when they are in good condition, have one or more tracks that might fail to verify due to a scratch or physical defect. Surely if more than half of the tracks are successful matches, that's enough to know that is the proper offset?

    opened by eharris 0
  • Read/Verify cycle is inefficient and should be improved

    Read/Verify cycle is inefficient and should be improved

    The read/verify cycle of whipper is pretty inefficient and I think it could be dramatically improved. Instead of re-reading and re-verifying the track if there is a mismatch, it should instead just reuse the previous verify pass as the source of the read pass on the next try instead of starting from scratch with a fresh read. The chances of a verification match success would be just as likely, but the number of extraction reads would be only half as much, and would allow for more retries without increasing the extraction time.

    opened by eharris 0
  • Add ability to rip just particular tracks from a CD

    Add ability to rip just particular tracks from a CD

    I often want to try re-ripping certain tracks of a CD over again using different settings, and don't want to waste time re-ripping tracks that were already successful. So it's annoying that there doesn't seem to be a way to tell whipper to do just a particular track (or tracks) of a CD.

    opened by eharris 0
  • Command line flags need a way to negate/flip behavior

    Command line flags need a way to negate/flip behavior

    There are some command line flags that enable certain options, but there doesn't seem to be a way to disable that option on the command line if it is enabled in the config file.

    For instance whipper cd rip --keep-going does not have a way to disable that option on the command line if it is enabled in the config file.

    Example use case: I have a couple of different CD drives I use to rip, and one of them is affected by the cdparanoia bug with drives with high read offset (see #234), so I have to use the buggy version of cdparanoia to be able to use that drive. I only use that drive when I'm trying to speed up the rip process of multiple CD's, and I only keep the results if the rip is completely error free, otherwise I re-rip it in the other more reliable drive.

    Because the more reliable drive is the drive I use most often, I have keep_going = True in my whipper.conf file. But when I'm using the less reliable drive, I want it to stop immediately if it has a problem since I'm not going to keep the results of that rip anyway, but there's no way currently to disable that option on the command line.

    An alternative for this specific case would be to allow the keep_going option to be in the drive specific config block, and have its presence there override the one in the [whipper.cd.rip] config block.

    opened by eharris 0
Releases(v0.10.0)
  • v0.10.0(May 17, 2021)

    v0.10.0 (2021-05-17)

    Full Changelog

    Implemented enhancements:

    • Add checks and warnings for (known) cdparanoia's upstream bugs #495 [Design]
    • Allow configuring whether to auto close the drive's tray #488
    • Better error handling for unconfigured drive offset #478 [Design]
    • WARNING:whipper.command.main:set_hostname() takes 1 positional argument but 2 were given #464 [Design]
    • Display release country in matching releases #451
    • Ability to group multi-disc releases in a single folder #448
    • Provide option to not use disambiguation in title #440
    • test_result_logger.py: truly test all four cases of whipper version scheme #427
    • more template options for filenames #401
    • Always print output directory #393 [Design]
    • Provide better error message when there's no CD in the drive #385 [Design]
    • Change documentation from epydoc to reStructuredText #383
    • Allow customization of maximum rip retries attempts value #349
    • Save ISRCs from CD TOC #320
    • PathFilter questions #313
    • Let debug musicbrainzngs look up based on MusicBrainz Release ID in addition to Disc ID #251
    • Ability to skip unrippable track #128
    • add manpage #73
    • Grab cover art #50
    • cdda2wav from cdrtools instead of cdparanoia #38

    Fixed bugs:

    • Unable to find offset with a single-track cd #532
    • Rip of CD fails to set "Various Artists" flac tag #518
    • AccurateRipResponse test failures #515
    • path_filter_whitespace not working #513
    • got exception IndexError('list index out of range') #512
    • no CD detected, please insert one and retry #511 [Regression]
    • whipper not finding the drive (whipper docker install) #499
    • Missing .toc files when ripping a CD multiple times due to whipper ToC caching #486
    • Change the docker alias in the readme to use {HOME} rather than ~ #482
    • Musicbrainz lookup fails for multiple CD rip #477
    • whipper drive analyze appears to be stuck #469 [Upstream Bug]
    • Whipper configuration file: cover_art option does nothing #465 [Design]
    • Improve Docker instructions in README #452
    • Whipper gives up even if 5th rip attempt is successful #449
    • Don't include full file path in log files #445 [Regression]
    • Whipper example config file: % character in inline comment causes InterpolationSyntaxError #443
    • output directory isn't read #441 [Regression]
    • Requests to accuraterip.com are missing a user agent which identifies whipper #439
    • Bug: MusicBrainz lookup URL is hardcoded to always use https #437
    • whipper drive analyze is broken on Python 3 #431 [Regression]
    • Make it possible to build from tarball again #428 [Regression]
    • TypeError: float argument required, not NoneType #402
    • Drop whipper caching #335
    • musicbrainz calculation fails on cd with data tracks that are not positioned at the end #289
    • AttributeError: 'Namespace' object has no attribute 'offset' #230 [Regression]
    • 'NoneType' object has no attribute '__getitem__' after rip with current master (a3e9260) #196
    • Use the track title instead the recoding title (MusicBrainz related) #192
    • pygobject_register_sinkfunc is deprecated #45

    Merged pull requests:

    • Fixed error when ripping using --keep-going without specifying `--o… #537 (blueblots)
    • Add requested template variables #536 (JoeLametta)
    • Added --keep-going option to cd rip command #524 (blueblots)
    • Parameterise the UID of the worker user in the docker build file. #517 (unclealex72)
    • Fix capitalization of "Health status" in rip log #510 (MasterOdin)
    • Tag audio tracks with ISRCs (if available) #509 (JoeLametta)
    • Provide better error message when there's no CD in the drive #507 (JoeLametta)
    • Add checks and warnings for (known) cdparanoia's upstream bugs #506 (JoeLametta)
    • Allow configuring whether to auto close the drive's tray #505 (JoeLametta)
    • Travis CI: Add Python 3.9 release candidate 1 #504 (cclauss)
    • Define libcdio version as environment variables in docker #498 (MasterOdin)
    • Add man pages. #490 (baldurmen)
    • Restore the ability to use inline comments in config files #461 (neilmayhew)
    • Fix cd rip --max-retries option handling #460 (kevinoid)
    • Fix crash fetching cover art for unknown album #459 (kevinoid)
    • Fix cover file saving with /tmp on different FS #458 (kevinoid)
    • Test all four cases of whipper version scheme #456 (ABCbum)
    • Allow customization of maximum rip attempts value #455 (ABCbum)
    • Update docker instructions to use --bind instead of -v. #454 (MartinPaulEve)
    • Use https and http appropriately when connecting to MusicBrainz #450 (ABCbum)
    • Add PERFORMER & COMPOSER metadata tags to audio tracks (if available) #444 (ABCbum)
    • Grab cover art from MusicBrainz/Cover Art Archive and add it to the resulting whipper rips #436 (ABCbum)
    • Fix whipper's MusicBrainz Disc ID calculation for CDs with data tracks that are not positioned at the end of the disc #435 (ABCbum)
    • Fix failed() task of AnalyzeTask (program/cdparanoia) #434 (Freso)
    • Test against Python versions 3.6, 3.7, and 3.8 #433 (Freso)
    • Allow whipper's mblookup command to look up information based on Release MBID #432 (ABCbum)
    • Enable whipper to use track title #430 (ABCbum)
    • Improve docstrings #389 (JoeLametta)
    • Drop whipper caching #336 (JoeLametta)
    • Rewrite PathFilter #324 (JoeLametta)
    Source code(tar.gz)
    Source code(zip)
  • v0.9.0(Dec 4, 2019)

  • v0.8.0(Oct 27, 2019)

    v0.8.0 (2019-10-27)

    Full Changelog

    Fixed bugs:

    • whipper bails out if MusicBrainz release group doesn’t have a type #396
    • object has no attribute 'working_directory' when running cd info #375
    • Failure to rip CD: "ValueError: could not convert string to float: " #374
    • "AttributeError: Program instance has no attribute '_presult'" when ripping #369
    • Drive analysis fails #361
    • Eliminate warning "eject: CD-ROM tray close command failed" #354
    • Flac file permissions #284

    Closed issues:

    • Separate out Release in log into two value map #416
    • Network issue #412
    • RequestsDependencyWarning: urllib3 (1.25.2) or chardet (3.0.4) doesn't match a supported version #400
    • Run script after rip #394
    • Add git/mercurial dependency to the README #386
    • Include MusicBrainz Release ID in the log file #381
    • Rip while entering MusicBrainz data #360
    • Doesn't eject - "eject: unable to eject" (but manual eject works) #355
    • Note in the whipper output/log if development version was used #337
    • fedora 29, whipper 0.72, Error While Executing Any Command #332
    • read-toc progress information #299
    • ripping fails frequently, but not repeatably #290
    • Look into adding more MusicBrainz identifiers to ripped files #200

    Merged pull requests:

    • Fix ripping discs with less than ten tracks #418 (mtdcr)
    • Make getFastToc() fast again #417 (mtdcr)
    • Use ruamel.yaml for formatting and outputting rip .log file #415 (itismadness)
    • Handle missing self.options for whipper cd info #410 (JoeLametta)
    • Fix erroneous result message for whipper drive analyze #409 (JoeLametta)
    • Report eject's failures as logger warnings #408 (JoeLametta)
    • Set FLAC files permissions to 0644 #407 (JoeLametta)
    • Fix offset find command #406 (vmx)
    • Make whipper not break on missing release type #398 (Freso)
    • Set default for eject to: success #392 (gorgobacka)
    • Use eject value of the class again #391 (gorgobacka)
    • Convert documentation from epydoc to reStructuredText #387 (JoeLametta)
    • Include MusicBrainz Release URL in log output #382 (Freso)
    • Specify supported version(s) of Python in setup.py #378 (Freso)
    • Fix critical regressions introduced in 3e79032 and 16b0d8d #371 (JoeLametta)
    • Use git to get whipper's version #370 (Freso)
    • Handle artist MBIDs as multivalue tags #367 (Freso)
    • Add Track, Release Group, and Work MBIDs to ripped files #366 (Freso)
    • Refresh MusicBrainz JSON responses used for testing #365 (Freso)
    • Clean up MusicBrainz nomenclature #364 (Freso)
    • Fix misaligned output in command.mblookup #363 (Freso)
    • Update accuraterip-checksum #362 (Freso)
    • Require Developer Certificate of Origin sign-off #358 (JoeLametta)
    • Address warnings/errors from various static analysis tools #357 (JoeLametta)
    • Clarify format option for disc template #353 (rekh127)
    • Refactor cdrdao toc/table functions into Task and provide progress output #345 (jtl999)
    • accuraterip-checksum: convert to python C extension #274 (mtdcr)
    Source code(tar.gz)
    Source code(zip)
  • v0.7.3(Dec 14, 2018)

    v0.7.3 (2018-12-14)

    Full Changelog

    Fixed bugs:

    • Error when parsing log file due to left pad track number #340
    • Failing AccurateRipResponse tests #333
    • CRITICAL:whipper.command.cd:output directory is a finished rip output directory #287
    • Possible HTOA error #281
    • Disc template KeyError #279
    • Enhanced CD causes computer to freeze. #256
    • pycdio & libcdio issues #238
    • Unicode issues #215
    • whipper offset find exception #208
    • ZeroDivisionError: float division by zero #202
    • Allow plugins from system directories #135

    Closed issues:

    • On Ubuntu 18.10 cd-paranoia binary is called cdparanoia #347
    • WARNING:whipper.common.program:network error: NetworkError() #338
    • Can not install #314
    • Write musicbrainz_discid tag when disc is unknown #280
    • Write .toc files in addition to .cue files to support cdrdao and non-compliant .cue sheets #214

    Merged pull requests:

    Source code(tar.gz)
    Source code(zip)
  • v0.7.2(Oct 31, 2018)

    v0.7.2 (2018-10-31)

    Full Changelog

    Implemented enhancements:

    • Add whipper to Hydrogen Audio wiki's "Comparison of CD rippers" #317
    • automatically build Docker images #301

    Fixed bugs:

    • UnicodeEncodeError: 'ascii' codec can't encode characters in position 17-18: ordinal not in range(128) #315

    Closed issues:

    • Make 0.7.1 release (before GCI 😅) #312

    Merged pull requests:

    • Explicitly encode path as UTF-8 in truncate_filename() #319 (Freso)
    • Add AppStream metainfo.xml file #318 (Freso)
    Source code(tar.gz)
    Source code(zip)
  • v0.7.1(Oct 23, 2018)

    v0.7.1 (2018-10-23)

    Full Changelog

    Implemented enhancements:

    • Transfer repository ownership to GitHub organization #306
    • Add cdparanoia version to log file #267
    • Remove whipper's retag feature #262
    • Add a requirements.txt file #221
    • Limit length of filenames #197
    • Loggers #117

    Fixed bugs:

    • TypeError on whipper offset find #263
    • Catch DNS error #206

    Closed issues:

    • Disable eject button when ripping #308
    • Github repo #293

    Merged pull requests:

    Source code(tar.gz)
    Source code(zip)
  • v0.7.0(Apr 9, 2018)

    v0.7.0 (2018-04-09)

    Full Changelog

    Implemented enhancements:

    Fixed bugs:

    • ImportError: libcdio.so.16: cannot open shared object file: No such file or directory #229
    • whipper offset find exception #208
    • cd rip is not able to rip the last track #203
    • whipper not picking up all settings in whipper.conf #99
    • fix CI build error with latest pycdio #233 (thomas-mc-work)

    Closed issues:

    • Make a 0.6.0 release #219
    • CD-ROM powers off during rip command. #189
    • Remove connection to parent fork. #79
    • GUI frontend for whipper #40

    Merged pull requests:

    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Feb 2, 2018)

    New backward incompatible changes in this release:

    • Rely on cd-paranoia (libcdio-cdparanoia) instead of cdparanoia (Xiph): changed dependency (PR #213 / whipper v0.6.0)
    • Introduced AccurateRip v2 support: added new requests python dependency (PR #187 / whipper v0.6.0)
    • Added CD-R media type disc detection: CD-R rips are now prevented by default (PR #154 / whipper v0.6.0)
    • Changed all morituri references to whipper: renamed python module and logger too (PR #109 / whipper v0.6.0)

    Added radon reports in misc/radon_reports folder.

    Source code(tar.gz)
    Source code(zip)
  • v0.5.1(Apr 24, 2017)

  • v0.5.0(Apr 24, 2017)

    Changes

    • Added pre-emphasis status reporting to whipper's logfiles
    • Whipper is now GStreamer free (removed all dependencies on it)
    • Replaced rip command suggestions with 'whipper'
    • Various bugfixes and improvements

    Known issues

    • #99 (whipper not picking up all settings in whipper.conf)
    • The image retag feature has been knowingly broken since PR #130
    Source code(tar.gz)
    Source code(zip)
  • v0.4.2(Jan 8, 2017)

  • v0.4.1(Jan 7, 2017)

    Changes

    • Updated top level informational files
    • Used soxi instead of gstreamer to determine a track's length
    • Error reporting enhancements
    • Updated README
    • Added Argparse & removed external git submodules
    • Update suggested commands given by drive list
    • Updated setup.py
    • Fixed bug (False value not being persisted correctly for defeat_cache)
    • Improved cdrdao error handling & ejection behavior

    Known issues

    #99 (whipper not picking up all settings in whipper.conf)

    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Nov 8, 2016)

    • Replace cdrdao.py with much simpler version
    • Logger update
    • Raise Exception when track rip runs out of attempts
    • Undelete overzealously removed plugin initialisation (fix regression)
    • Invoke whipper by its name & README rewrite
    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Nov 8, 2016)

  • v0.2.4(Oct 9, 2016)

Owner
null
Gateware for the Terasic/Arrow DECA board, to become a USB2 high speed audio interface

DECA USB Audio Interface DECA based USB 2.0 High Speed audio interface Status / current limitations enumerates as class compliant audio device on Linu

Hans Baier 16 Mar 21, 2022
Audio spatialization over WebRTC and JACK Audio Connection Kit

Audio spatialization over WebRTC Spatify provides a framework for building multichannel installations using WebRTC.

Bruno Gola 34 Jun 29, 2022
cross-library (GStreamer + Core Audio + MAD + FFmpeg) audio decoding for Python

audioread Decode audio files using whichever backend is available. The library currently supports: Gstreamer via PyGObject. Core Audio on Mac OS X via

beetbox 419 Dec 26, 2022
Audio fingerprinting and recognition in Python

dejavu Audio fingerprinting and recognition algorithm implemented in Python, see the explanation here: How it works Dejavu can memorize audio by liste

Will Drevo 6k Jan 6, 2023
Python library for audio and music analysis

librosa A python package for music and audio analysis. Documentation See https://librosa.org/doc/ for a complete reference manual and introductory tut

librosa 5.6k Jan 6, 2023
Python Audio Analysis Library: Feature Extraction, Classification, Segmentation and Applications

A Python library for audio feature extraction, classification, segmentation and applications This doc contains general info. Click here for the comple

Theodoros Giannakopoulos 5.1k Jan 2, 2023
Scalable audio processing framework written in Python with a RESTful API

TimeSide : scalable audio processing framework and server written in Python TimeSide is a python framework enabling low and high level audio analysis,

Parisson 340 Jan 4, 2023
nicfit 425 Jan 1, 2023
Python module for handling audio metadata

Mutagen is a Python module to handle audio metadata. It supports ASF, FLAC, MP4, Monkey's Audio, MP3, Musepack, Ogg Opus, Ogg FLAC, Ogg Speex, Ogg The

Quod Libet 1.1k Dec 31, 2022
Read music meta data and length of MP3, OGG, OPUS, MP4, M4A, FLAC, WMA and Wave files with python 2 or 3

tinytag tinytag is a library for reading music meta data of MP3, OGG, OPUS, MP4, M4A, FLAC, WMA and Wave files with python Install pip install tinytag

Tom Wallroth 577 Dec 26, 2022
Telegram Voice-Chat Bot Written In Python Using Pyrogram.

Telegram Voice-Chat Bot Telegram Voice-Chat Bot To Play Music From Various Sources In Your Group Support All linux based os. Windows Mac Diagram Requi

TheHamkerCat 314 Dec 29, 2022
Expressive Digital Signal Processing (DSP) package for Python

AudioLazy Development Last release PyPI status Real-Time Expressive Digital Signal Processing (DSP) Package for Python! Laziness and object representa

Danilo de Jesus da Silva Bellini 642 Dec 26, 2022
cross-library (GStreamer + Core Audio + MAD + FFmpeg) audio decoding for Python

audioread Decode audio files using whichever backend is available. The library currently supports: Gstreamer via PyGObject. Core Audio on Mac OS X via

beetbox 359 Feb 15, 2021
Python wrapper around sox.

pysox Python wrapper around sox. Read the Docs here. This library was presented in the following paper: R. M. Bittner, E. J. Humphrey and J. P. Bello,

Rachel Bittner 446 Dec 7, 2022
Python I/O for STEM audio files

stempeg = stems + ffmpeg Python package to read and write STEM audio files. Technically, stems are audio containers that combine multiple audio stream

Fabian-Robert Stöter 72 Dec 23, 2022
Read music meta data and length of MP3, OGG, OPUS, MP4, M4A, FLAC, WMA and Wave files with python 2 or 3

tinytag tinytag is a library for reading music meta data of MP3, OGG, OPUS, MP4, M4A, FLAC, WMA and Wave files with python Install pip install tinytag

Tom Wallroth 435 Feb 17, 2021
Python library for handling audio datasets.

AUDIOMATE Audiomate is a library for easy access to audio datasets. It provides the datastructures for accessing/loading different datasets in a gener

Matthias 121 Nov 27, 2022
python wrapper for rubberband

pyrubberband A python wrapper for rubberband. For now, this just provides lightweight wrappers for pitch-shifting and time-stretching. All processing

Brian McFee 106 Nov 28, 2022
Expressive Digital Signal Processing (DSP) package for Python

AudioLazy Development Last release PyPI status Real-Time Expressive Digital Signal Processing (DSP) Package for Python! Laziness and object representa

Danilo de Jesus da Silva Bellini 573 Feb 8, 2021