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 replace 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
    • The package named libcdio-utils, available on certain Debian and Ubuntu versions, is affected by a bug: it doesn't include the cd-paranoia binary (needed by whipper). Only Debian bullseye (testing) / sid (unstable) and Ubuntu focal (20.04) and later versions have a separate cd-paranoia package where the binary is provided. For more details on this issue check the relevant bug reports: #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 on 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.

To build the man pages, follow the instructions in the relevant README which is located in the man subfolder.

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.

    Please note that whipper's offset find feature is quite primitive so it may not always achieve its task: in this case using the value listed in AccurateRip's CD Drive Offset database should be enough.

    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.

Please note that locally installed logger plugins won't be recognized when whipper has been installed through the official Docker image.

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

Finally, 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:

Issues
  • 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 29
  • 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
  • Port to Python 3

    Port to Python 3

    Bug Accepted Priority: high Needed: patch 
    opened by mr-bo-jangles 25
  • Support both AccurateRip V1 and AccurateRip V2 at the same time

    Support both AccurateRip V1 and AccurateRip V2 at the same time

    This one is kindly being worked on by MerlijnWajer.

    https://github.com/thomasvs/morituri/issues/119#issuecomment-172170456

    Accepted Feature 
    opened by JoeLametta 24
  • 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
  • Better --prompt Handling

    Better --prompt Handling

    I always use the --prompt option to ensure that the correct release is choosen, but the process of choosing one is a bit ambiguous. My first guess was to enter the index number of the displayed release that I wanted (1 for the first one, 2 for the second one and so on) but that was incorrect. I had to look through the source to see how to do it.

    So I added a little message for the user to make things more clear. I also made the input case-insensitive so that 25EA4 will match with 25ea4.

    opened by BioBox 0
  • is the application currently considered reliable?

    is the application currently considered reliable?

    Please excuse me if anyone would prefer that such a question not be given through this system, but I find the specific information nowhere I have looked, nor find any other place to ask.

    Is the application currently mature enough that a ripped image it produces, assuming no error or warning occurred during the process, may be considered reliable, that is, accurate and complete, to the same degree as other from software (e.g. EAC)?

    opened by brainchild0 6
  • Drop EAClogger as official logger?

    Drop EAClogger as official logger?

    https://github.com/whipper-team/whipper-plugin-eaclogger hasn’t received any commits since 2019, which is also the last time for any activity in the issues (last PR is from 2017).

    We still mention it as an official logger in the README, and while I do see utility in keeping the log extensibility, maybe it’s time to retire the official-ness of the EAC-logger and archive that repository? (Archiving allows others to fork it if they so desire, so that development can continue.)

    Priority: low Needed: discussion 
    opened by Freso 0
  • Store and reuse TOC

    Store and reuse TOC

    It can take some time for whipper cd info to finish reading the TOC. When starting whipper cd rip the same process is repeated. Providing a way to store the TOC when using info and reusing the same when following up with a rip would speed up the process a bit.

    While it being just a rough idea, several things come to mind:

    • Allow providing a parameter for a file name for info and rip to subsequently save the TOC and read the TOC from
    • Maybe even store the TOC as a cached file and automatically reuse it when available
    • In case of the latter as default behaviour a parameter to disable TOC caching might be useful
    • Add a check for e.g. disc ID when reusing a TOC file to make sure there's no mismatch

    In addition to a speed-up for when you happen to use info before rip, it would also function as groundwork for a possible Whipper GUI in the future. You'd want to systematically view the disc content before ripping.

    Feature On Hold Needed: discussion 
    opened by Forage 3
  • possible (new) method of doing audio cd quality error rate analysis?

    possible (new) method of doing audio cd quality error rate analysis?

    Stumbled upon a twitter post by Hector Martin @marcan quoted: https://twitter.com/marcan42/status/1381544164832108545

    ... There's no way to get raw error counts (pre ECC) off of most CD-ROM drives, but the subchannel has no ECC, so that works as a proxy for quality...

    He uses subchannel "without ecc" data to be able to do audio CD error rate analysis by comparing it with normal ecc corrected data: https://github.com/marcan/cd-analysis

    Not sure if this insight is new, or even usefull for this whipper project CDR/CD. I only found reference in libcdio changelog 1.0 of dropping subchannel support.

    Feel free to use/close this issue.

    Feature On Hold Needed: discussion 
    opened by walterav1984 3
  • Exception when querying newly created entry in MusicBrainz database

    Exception when querying newly created entry in MusicBrainz database

    I've seen this exception a couple of times just after having added a new Disc ID to MusicBrainz:

    Traceback (most recent call last):
      File "[...]/bin/whipper", line 11, in <module>
        load_entry_point('whipper==0.9.1.dev110+geeba910', 'console_scripts', 'whipper')()
      File "[...]/lib/python3.8/site-packages/whipper-0.9.1.dev110+geeba910-py3.8-linux-x86_64.egg/whipper/command/main.py", line 56, in main
        ret = cmd.do()
      File "[...]/lib/python3.8/site-packages/whipper-0.9.1.dev110+geeba910-py3.8-linux-x86_64.egg/whipper/command/basecommand.py", line 141, in do
        return self.cmd.do()
      File "[...]/lib/python3.8/site-packages/whipper-0.9.1.dev110+geeba910-py3.8-linux-x86_64.egg/whipper/command/basecommand.py", line 141, in do
        return self.cmd.do()
      File "[...]/lib/python3.8/site-packages/whipper-0.9.1.dev110+geeba910-py3.8-linux-x86_64.egg/whipper/command/cd.py", line 115, in do
        self.program.getMusicBrainz(self.ittoc, self.mbdiscid,
      File "[...]/lib/python3.8/site-packages/whipper-0.9.1.dev110+geeba910-py3.8-linux-x86_64.egg/whipper/common/program.py", line 293, in getMusicBrainz
        metadatas = mbngs.musicbrainz(mbdiscid,
      File "[...]/lib/python3.8/site-packages/whipper-0.9.1.dev110+geeba910-py3.8-linux-x86_64.egg/whipper/common/mbngs.py", line 423, in musicbrainz
        logger.debug('duration %r', md.duration)
    AttributeError: 'DiscMetadata' object has no attribute 'duration'
    

    I have never seen it happen twice in a row. I think whipper should either catch this exception and retry a few times, waiting a few seconds between new attempts, or fail gracefully advising the user to retry later.

    opened by mtdcr 2
  • `whipper cd rip` results in error reading TOC

    `whipper cd rip` results in error reading TOC

    Steps to Reproduce

    1. Insert specific CDs (https://musicbrainz.org/release-group/e1ba148a-2a49-3a64-8c27-0d894aff56fe)
    2. $ whipper cd -d /dev/sr1 rip

    Expected Results

    CD whips

    Actual

    Throws a stack trace in my one drive, not in my other. Very strange

    Stack trace

    Traceback (most recent call last):
      File "/usr/lib/python3.9/site-packages/whipper/extern/task/task.py", line 523, in c
        callable_task(*args, **kwargs)
      File "/usr/lib/python3.9/site-packages/whipper/program/cdrdao.py", line 115, in _read
        self._done()
      File "/usr/lib/python3.9/site-packages/whipper/program/cdrdao.py", line 153, in _done
        self.toc.parse()
      File "/usr/lib/python3.9/site-packages/whipper/image/toc.py", line 202, in parse
        with open(self._path) as f:
    FileNotFoundError: [Errno 2] No such file or directory: '/tmp/tmp7foc7nnu.cdrdao.read-toc.whipper.task'
    

    Reproducibility

    This happened twice on the same CD and not before it. The next CD in my library read the TOC fine.

    Environment & Drive info

    OS: Arch Linux Kernel: Linux 5.11.7-arch1-1 #1 SMP PREEMPT Wed, 17 Mar 2021 16:59:58 +0000 x86_64 GNU/Linux Build: whipper-git 0.9.1.dev109+g87f3d00-1

    Bad Drive

    [drive:TSSTcorp%3ACDDVDW%20SH-S203N%20%3ASB02]
    vendor = TSSTcorp
    model = CDDVDW SH-S203N
    release = SB02
    defeats_cache = True
    read_offset = 6
    

    Good drive

    [drive:HL-DT-ST%3ADVDRAM%20GH24NS90%20%3AIN01]
    vendor = HL-DT-ST
    model = DVDRAM GH24NS90
    release = IN01
    defeats_cache = False
    read_offset = 6
    
    Bug Needed: replication On Hold 
    opened by Bujiraso 7
  • Reword 'track  n: unknown          (error)' to reflect missing from AccurateRip DB

    Reword 'track n: unknown (error)' to reflect missing from AccurateRip DB

    Hello,

    This wording catches me off guard wrong and I continually check for errors but it looks like the track is simply missing from the database.

    Could this be re-worded to

    "track n: unknown          (track not present in AccurateRip database for verification)"
    

    ?

    I'm used to "error" meaning I need to do something, but as far as I understand there's nothing I can do here. The extra info would be helpful so I don't need to crack the .log file open each time.

    Let me know if this seems something worth a "beginner" PR from me! Thanks!

    Design On Hold Needed: discussion 
    opened by Bujiraso 4
  • Feature Request: Quick reference - List all commands, subcommands and their potential arguments somewhere

    Feature Request: Quick reference - List all commands, subcommands and their potential arguments somewhere

    First off, thanks for writing help's for each command!

    I would find it most helpful if the output of the base whipper --help had the potential arguments that could be passed to each sub-command as a "cheat sheet" or "quick reference".

    Instead of

      cd       handle CDs
    

    It would say

     cd [-h] [-d DEVICE]        handle CDs
                  info [-h] [-R RELEASE_ID] [-p] [-c COUNTRY]
                  rip [-h] [-R RELEASE_ID] [-p] [-c COUNTRY] [-L LOGGER] [-o OFFSET] [-x] [-O OUTPUT_DIRECTORY] [-W WORKING_DIRECTORY] [--track-template TRACK_TEMPLATE] [--disc-template DISC_TEMPLATE] [-U] [--cdr]
    

    Is there already a quick reference of all commands? Any "quick reference" help file would satisfy this -- how about a man page? :smiley:

    opened by Bujiraso 0
  • Handle FreeDB's connection failures more gracefully

    Handle FreeDB's connection failures more gracefully

    Running on Ubuntu 18.04, using a docker pull image. When a disc is found in MusicBrainz, whipper works correctly, but when there is no match, it crashes in freedb_command. It looks like gnudb.gnudb.org may be misconfigured at the moment - but my read of the code suggests whipper should "fail gracefully". Not sure how to fix this.

    `whipper cd rip -U INFO:whipper.command.cd:using configured read offset 6 INFO:whipper.command.cd:checking device /dev/cdrom WARNING:whipper.program.utils:command 'eject -t /dev/cdrom' returned with exit code '1' (b'eject: CD-ROM tray close command failed: Input/output error') CDDB disc id: 340fe716 MusicBrainz disc id hbVl1HmM9DuFTmU7W7q90qAB_jc- MusicBrainz lookup URL https://musicbrainz.org/cdtoc/attach?toc=1+22+305485+150+11982+25877+35360+49115+60500+70647+83300+95770+107817+119372+135082+147082+163440+180572+195295+214360+228227+246357+258635+278310+291302&tracks=22&id=hbVl1HmM9DuFTmU7W7q90qAB_jc- Disc duration: 01:07:51.133, 22 audio tracks WARNING:whipper.common.program:release not found: (NotFoundException(ResponseError()),) WARNING:whipper.common.program:continuing without metadata Submit this disc to MusicBrainz at the above URL.

    Traceback (most recent call last): File "/usr/local/bin/whipper", line 11, in load_entry_point('whipper==0.9.0', 'console_scripts', 'whipper')() File "/usr/local/lib/python3.7/dist-packages/whipper-0.9.0-py3.7-linux-x86_64.egg/whipper/command/main.py", line 43, in main ret = cmd.do() File "/usr/local/lib/python3.7/dist-packages/whipper-0.9.0-py3.7-linux-x86_64.egg/whipper/command/basecommand.py", line 139, in do return self.cmd.do() File "/usr/local/lib/python3.7/dist-packages/whipper-0.9.0-py3.7-linux-x86_64.egg/whipper/command/basecommand.py", line 139, in do return self.cmd.do() File "/usr/local/lib/python3.7/dist-packages/whipper-0.9.0-py3.7-linux-x86_64.egg/whipper/command/cd.py", line 119, in do cddbmd = self.program.getCDDB(cddbid) File "/usr/local/lib/python3.7/dist-packages/whipper-0.9.0-py3.7-linux-x86_64.egg/whipper/common/program.py", line 256, in getCDDB return [item['DTITLE'] for item in md if 'DTITLE' in item] or None File "/usr/local/lib/python3.7/dist-packages/whipper-0.9.0-py3.7-linux-x86_64.egg/whipper/common/program.py", line 256, in return [item['DTITLE'] for item in md if 'DTITLE' in item] or None File "/usr/local/lib/python3.7/dist-packages/whipper-0.9.0-py3.7-linux-x86_64.egg/whipper/extern/freedb.py", line 89, in perform_lookup line = next(query) File "/usr/local/lib/python3.7/dist-packages/whipper-0.9.0-py3.7-linux-x86_64.egg/whipper/extern/freedb.py", line 189, in freedb_command urlencode(POST).encode()) File "/usr/lib/python3.7/urllib/request.py", line 222, in urlopen return opener.open(url, data, timeout) File "/usr/lib/python3.7/urllib/request.py", line 525, in open response = self._open(req, data) File "/usr/lib/python3.7/urllib/request.py", line 543, in _open '_open', req) File "/usr/lib/python3.7/urllib/request.py", line 503, in _call_chain result = func(*args) File "/usr/lib/python3.7/urllib/request.py", line 1352, in http_open return self.do_open(http.client.HTTPConnection, req) File "/usr/lib/python3.7/urllib/request.py", line 1327, in do_open r = h.getresponse() File "/usr/lib/python3.7/http/client.py", line 1336, in getresponse response.begin() File "/usr/lib/python3.7/http/client.py", line 306, in begin version, status, reason = self._read_status() File "/usr/lib/python3.7/http/client.py", line 275, in _read_status raise RemoteDisconnected("Remote end closed connection without" http.client.RemoteDisconnected: Remote end closed connection without response `

    Accepted Design Improvement 
    opened by lawiedc 4
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.3.0(Nov 8, 2016)

  • 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.2.4(Oct 9, 2016)

🎚️ Open Source Audio Matching and Mastering

Matching + Mastering = ❤️ Matchering 2.0 is a novel Containerized Web Application and Python Library for audio matching and mastering. It follows a si

Sergey Grishakov 489 Sep 14, 2021
Bule-ish CD ripper

cyanrip Fully featured CD ripping program able to take out most of the tedium. Fully accurate, has advanced features most rippers don't, yet has no bl

Lynne 57 Jun 30, 2021
Fork of the original rubyripper from code.google.com/p/rubyripper + some bugs fixes

Historical note Introduction Secure rip method How to install MacOS Support FAQ Running all tests Historical note This is an unofficial fork of the or

null 91 Aug 11, 2021
Javascript audio library for the modern web.

Description howler.js is an audio library for the modern web. It defaults to Web Audio API and falls back to HTML5 Audio. This makes working with audi

James Simpson 19k Sep 15, 2021
The gPodder podcast client.

___ _ _ ____ __ _| _ \___ __| |__| |___ _ _ |__ / / _` | _/ _ \/ _` / _` / -_) '_| |_ \ \__, |_| \___/\__,_\__,_\___|_| |_

gPodder and related projects 892 Sep 14, 2021
Ear-bending noises and music

Cecilia5 - the audio processing toolbox Cecilia is an audio signal processing environment. Cecilia lets you create your own GUI (grapher, sliders, tog

Olivier Bélanger 128 Sep 12, 2021
Audio Editor

Audacity is an easy-to-use, multi-track audio editor and recorder for Windows, Mac OS X, GNU/Linux and other operating systems. Developed by a group o

Audacity 6.4k Sep 17, 2021
Mixxx is Free DJ software that gives you everything you need to perform live mixes.

Mixxx Mixxx is Free DJ software that gives you everything you need to perform live DJ mixes. Mixxx works on GNU/Linux, Windows, and macOS. Quick Start

Mixxx DJ Software 2.4k Sep 17, 2021
Esoteric Programming Language

ORCΛ Orca is an esoteric programming language designed to quickly create procedural sequencers, in which every letter of the alphabet is an operation,

Hundredrabbits 3.4k Sep 14, 2021
C++ library and Python bindings for the Music Encoding Initiative format

LibMEI LibMEI is a C++ library for reading and writing MEI files It is developed by the Distributed Digital Music Archives and Libraries Lab at the Sc

Distributed Digital Music Archives and Libraries Lab 49 Aug 30, 2021
Standalone lyrics fetcher/displayer (windowed and OSD mode).

OSD Lyrics Show synced lyrics with your favorite media player on Linux. Introduction OSD Lyrics is a desktop application to view lyrics compatible wit

OSD Lyrics 242 Aug 27, 2021
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 4.7k Sep 15, 2021
A language for music notation

Lydown is a language and compiler for creating music scores, parts and snippets. The lydown code is compiled to lilypond code and then compiled to PDF

Sharon Rosner 21 Apr 8, 2021
Typographic Beat-Oriented Notation for music

tbon Typographic Beat-Oriented Notation for music Tbon aims to be the fastest way to enter pitches, rhythms, meter and dynamic levels from a computer

null 11 Jan 23, 2020
GTK 3 client for the Music Player Daemon - I'm looking for new maintainers!

Sonata is looking for new maintainers! I (@multani) don't use Sonata much anymore and as a consequence, I've been very slow to answer even to the few

Jonathan Ballet 123 Aug 28, 2021
Mopidy is an extensible music server written in Python

Mopidy Mopidy is an extensible music server written in Python. Mopidy plays music from local disk, Spotify, SoundCloud, Google Play Music, and more. Y

Mopidy 7.2k Sep 17, 2021
🎵 A simple, clean and cross-platform music player

Museeks A simple, clean and cross-platform music player. (museeks.io) Features Museeks aims to be a simple and easy to use music player with a clean U

Pierre de la Martinière 1.1k Sep 17, 2021
music library manager and MusicBrainz tagger

beets Beets is the media library management system for obsessive music geeks. The purpose of beets is to get your music collection right once and for

beetbox 10.4k Sep 15, 2021
🎵 Music notation engraving library for MEI with MusicXML and Humdrum support and various toolkits (JavaScript, Python)

Verovio is a fast, portable and lightweight library for engraving Music Encoding Initiative (MEI) digital scores into SVG images. Verovio also contain

RISM Digital Center 426 Sep 22, 2021