Merge branch 'master' into core-updates-frozen
[jackhill/guix/guix.git] / gnu / packages / music.scm
index 33abab6..cff7bc8 100644 (file)
@@ -17,7 +17,7 @@
 ;;; Copyright © 2018 nee <nee.git@hidamari.blue>
 ;;; Copyright © 2018, 2021 Stefan Reichör <stefan@xsteve.at>
 ;;; Copyright © 2018 Pierre Neidhardt <mail@ambrevar.xyz>
-;;; Copyright © 2018, 2019 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2018, 2019, 2021 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2018 Björn Höfling <bjoern.hoefling@bjoernhoefling.de>
 ;;; Copyright © 2019 Gabriel Hondet <gabrielhondet@gmail.com>
 ;;; Copyright © 2019 Timotej Lazar <timotej.lazar@araneo.si>
@@ -42,6 +42,7 @@
 ;;; Copyright © 2021 Justin Veilleux <terramorpha@cock.li>
 ;;; Copyright © 2021 Felix Gruber <felgru@posteo.net>
 ;;; Copyright © 2021 Simon Streit <simon@netpanic.org>
+;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
   #:use-module (gnu packages pulseaudio) ;libsndfile
   #:use-module (gnu packages python)
   #:use-module (gnu packages python-check)
+  #:use-module (gnu packages python-compression)
   #:use-module (gnu packages python-web)
   #:use-module (gnu packages python-xyz)
   #:use-module (gnu packages qt)
@@ -552,7 +554,7 @@ It is a fork of Clementine aimed at music collectors and audiophiles.")
 (define-public cmus
   (package
     (name "cmus")
-    (version "2.8.0")
+    (version "2.9.1")
     (source (origin
               (method git-fetch)
               (uri (git-reference
@@ -561,7 +563,7 @@ It is a fork of Clementine aimed at music collectors and audiophiles.")
               (file-name (git-file-name name version))
               (sha256
                (base32
-                "1ydnvq13ay8b8mfmmgwi5qsgyf220yi1d01acbnxqn775dghmwar"))))
+                "0zjkimni2fhv4yskrjrgj6b74f33rfj58zgd7khwrz4z8nf88j0w"))))
     (build-system gnu-build-system)
     (arguments
      `(#:tests? #f ; cmus does not include tests
@@ -630,7 +632,7 @@ many input formats and provides a customisable Vi-style user interface.")
              ;; Replace hard-coded diff file name.
              (substitute* "tests/integration.c"
                (("/usr/bin/diff")
-                (string-append (assoc-ref inputs "diffutils") "/bin/diff")))
+                (search-input-file inputs "/bin/diff")))
              ;; Denemo's documentation says to use this command to run its
              ;; test suite.
              (invoke "make" "-C" "tests" "check")))
@@ -638,8 +640,7 @@ many input formats and provides a customisable Vi-style user interface.")
            ;; This phase sets the default path for lilypond to its current
            ;; location in the store.
            (lambda* (#:key inputs #:allow-other-keys)
-             (let* ((lilypond (string-append (assoc-ref inputs "lilypond")
-                                             "/bin/lilypond")))
+             (let* ((lilypond (search-input-file inputs "/bin/lilypond")))
                (substitute* "src/core/prefops.c"
                  (("g_string_new \\(\"lilypond\"\\);")
                   (string-append "g_string_new (\""
@@ -1492,15 +1493,6 @@ and auto-mapping slices to MIDI note numbers.")
                             "/share/fonts/opentype/"))
        #:phases
        (modify-phases %standard-phases
-         (add-after 'unpack 'use-texlive-union
-           (lambda _
-             ;; FIXME: fonts are not found and have to be generated in HOME.
-             (setenv "HOME" "/tmp")
-             ;; The test for the "lh" package fails, even though it is among
-             ;; the inputs.
-             (substitute* "configure"
-               (("TEX_FIKPARM=.*") "TEX_FIKPARM=found\n"))
-             #t))
          (add-after 'unpack 'fix-path-references
            (lambda _
              (substitute* "scm/backend-library.scm"
@@ -1545,9 +1537,9 @@ and auto-mapping slices to MIDI note numbers.")
        ("gettext" ,gettext-minimal)
        ("imagemagick" ,imagemagick)
        ("netpbm" ,netpbm)               ;for pngtopnm
-       ("texlive" ,(texlive-union (list texlive-metapost
-                                        texlive-generic-epsf
-                                        texlive-latex-lh
+       ("texlive" ,(texlive-updmap.cfg (list texlive-metapost
+                                        texlive-epsf
+                                        texlive-lh
                                         texlive-latex-cyrillic)))
        ("texinfo" ,texinfo)
        ("texi2html" ,texi2html-1.82)
@@ -1597,7 +1589,7 @@ Guile.")
        ("python-iniconfig" ,python-iniconfig)
        ("python-isort" ,python-isort)
        ("python-mypy" ,python-mypy)
-       ("python-pytest" ,python-pytest-6)
+       ("python-pytest" ,python-pytest)
        ("python-pytest-cov" ,python-pytest-cov)
        ("python-sphinx-autodoc-typehints" ,python-sphinx-autodoc-typehints)))
     (inputs
@@ -1652,7 +1644,7 @@ typographic detail of symbols on the page.")
        ("python-iniconfig" ,python-iniconfig)
        ("python-isort" ,python-isort)
        ("python-mypy" ,python-mypy)
-       ("python-pytest" ,python-pytest-6)
+       ("python-pytest" ,python-pytest)
        ("python-pytest-cov" ,python-pytest-cov)
        ("python-pytest-helpers-namespace" ,python-pytest-helpers-namespace)))
     (propagated-inputs
@@ -1694,7 +1686,7 @@ and manipulating rhythms such as accelerandi, taleas, and more.")
        ("python-iniconfig" ,python-iniconfig)
        ("python-isort" ,python-isort)
        ("python-mypy" ,python-mypy)
-       ("python-pytest" ,python-pytest-6)
+       ("python-pytest" ,python-pytest)
        ("python-pytest-cov" ,python-pytest-cov)
        ("python-pytest-helpers-namespace" ,python-pytest-helpers-namespace)))
     (propagated-inputs
@@ -1741,7 +1733,7 @@ music theorist Paul Nauert's quantization grids or Q-Grids, for short.")
        ("python-iniconfig" ,python-iniconfig)
        ("python-isort" ,python-isort)
        ("python-mypy" ,python-mypy)
-       ("python-pytest" ,python-pytest-6)
+       ("python-pytest" ,python-pytest)
        ("python-pytest-cov" ,python-pytest-cov)
        ("python-pytest-helpers-namespace" ,python-pytest-helpers-namespace)))
     (propagated-inputs
@@ -1893,7 +1885,7 @@ complete studio.")
        `(("liblo" ,liblo)
          ("gtkmm" ,gtkmm)
          ("alsa-lib" ,alsa-lib)
-         ("libxmlplusplus" ,libxmlplusplus-2.6)))
+         ("libxml++" ,libxml++-2)))
       (native-inputs
        `(("glib:bin" ,glib "bin")
          ("pkg-config" ,pkg-config)))
@@ -2101,9 +2093,9 @@ for path in [path for path in sys.path if 'site-packages' in path]: site.addsite
            (lambda* (#:key inputs outputs #:allow-other-keys)
              ;; Make sure 'solfege' runs with the correct PYTHONPATH.
              (let* ((out (assoc-ref outputs "out"))
-                    (path (getenv "PYTHONPATH")))
+                    (path (getenv "GUIX_PYTHONPATH")))
                (wrap-program (string-append out "/bin/solfege")
-                 `("PYTHONPATH" ":" prefix (,path))))
+                 `("GUIX_PYTHONPATH" ":" prefix (,path))))
              #t)))))
     (inputs
      `(("python" ,python-2)
@@ -3209,9 +3201,7 @@ can connect to any JACK port and record the output into a stereo WAV file.")
              ;; Fix reference to dlopened libraries.
              (substitute* "jackselect/alsainfo.py"
                (("libasound.so.2")
-                (string-append (assoc-ref inputs "alsa-lib")
-                               "/lib/libasound.so.2")))
-             #t))
+                (search-input-file inputs "/lib/libasound.so.2")))))
          (replace 'build
            (assoc-ref python:%standard-phases 'build))
          (add-after 'install 'wrap
@@ -3482,8 +3472,7 @@ socket or command line.")
            (lambda* (#:key inputs #:allow-other-keys)
              (substitute* "curseradio/curseradio.py"
                (("/usr/bin/mpv")
-                (string-append (assoc-ref inputs "mpv") "/bin/mpv")))
-             #t)))))
+                (search-input-file inputs "/bin/mpv"))))))))
     (propagated-inputs
      `(("python-lxml" ,python-lxml)
        ("python-requests" ,python-requests)
@@ -3591,7 +3580,7 @@ formats, looking up tracks through metadata and audio fingerprints.")
      `(("python-pytest" ,python-pytest)
        ("python-hypothesis" ,python-hypothesis)
        ("python-flake8" ,python-flake8)))
-    (home-page "https://bitbucket.org/lazka/mutagen")
+    (home-page "https://mutagen.readthedocs.io/")
     (synopsis "Read and write audio tags")
     (description "Mutagen is a Python module to handle audio metadata.  It
 supports ASF, FLAC, M4A, Monkey’s Audio, MP3, Musepack, Ogg FLAC, Ogg Speex, Ogg
@@ -3629,18 +3618,14 @@ of tags.")
 (define-public python-musicbrainzngs
   (package
     (name "python-musicbrainzngs")
-    (version "0.6")
+    (version "0.7.1")
     (source (origin
               (method url-fetch)
               (uri (pypi-uri "musicbrainzngs" version))
               (sha256
                (base32
-                "1dddarpjawryll2wss65xq3v9q8ln8dan7984l5dxzqx88d2dvr8"))))
+                "09z6k07pxncfgfc8clfmmxl2xqbd7h8x8bjzwr95hc0bzl00275b"))))
     (build-system python-build-system)
-    (arguments
-     '(;; The tests fail suffer from race conditions:
-       ;; https://github.com/alastair/python-musicbrainzngs/issues/211
-       #:tests? #f))
     (home-page "https://python-musicbrainzngs.readthedocs.org/")
     (synopsis "Python bindings for MusicBrainz NGS webservice")
     (description "Musicbrainzngs implements Python bindings of the MusicBrainz
@@ -3710,37 +3695,29 @@ detailed track info including timbre, pitch, rhythm and loudness information.
 (define-public python-pylast
   (package
     (name "python-pylast")
-    (version "2.0.0")
+    (version "4.2.1")
     (source (origin
               (method url-fetch)
               (uri (pypi-uri "pylast" version))
               (sha256
                (base32
-                "0r9h7g8i8l2mgqjwkda3v6prfbkb2im5kap1az9ppmhjm9i4jkcf"))))
+                "0pzzhr4mlwpvfhy9gzq86ppz29fmf5z0w3xkl5if1fm59r1afms7"))))
     (build-system python-build-system)
     ;; Tests require network access.  See
     ;; https://github.com/pylast/pylast/issues/105
     (arguments '(#:tests? #f))
     (native-inputs
      `(("python-coverage" ,python-coverage)
-       ("python-pycodestyle" ,python-pycodestyle)
-       ("python-mock" ,python-mock)
-       ("python-pep8" ,python-pep8)
        ("python-pytest" ,python-pytest)
        ("python-flaky" ,python-flaky)
-       ("python-pyflakes" ,python-pyflakes)
-       ("python-pyyaml" ,python-pyyaml)))
-    (propagated-inputs
-     `(("python-six" ,python-six)))
+       ("python-pyyaml" ,python-pyyaml)
+       ("python-setuptools-scm" ,python-setuptools-scm)))
     (home-page "https://github.com/pylast/pylast")
     (synopsis "Python interface to Last.fm and Libre.fm")
     (description "A Python interface to Last.fm and other API-compatible
 websites such as Libre.fm.")
     (license license:asl2.0)))
 
-(define-public python2-pylast
-  (package-with-python2 python-pylast))
-
 (define-public instantmusic
   (let ((commit "300891d09c703525215fa5a116b9294af1c923c8")
         (revision "1"))
@@ -3786,34 +3763,27 @@ websites such as Libre.fm.")
 (define-public beets
   (package
     (name "beets")
-    (version "1.4.9")
+    (version "1.5.0")
     (source (origin
               (method url-fetch)
               (uri (pypi-uri "beets" version))
-              (patches (search-patches "beets-werkzeug-compat.patch"))
               (sha256
                (base32
-                "0m40rjimvfgy1dv04p8f8d5dvi2855v4ix99a9xr900cmcn476yj"))))
+                "0arl4nc3y8iwa331hf6ggai19y8ns9pl03g5d6ac857wq2x7nzw8"))))
     (build-system python-build-system)
     (arguments
      `(#:phases
        (modify-phases %standard-phases
-         ;; Reported upstream: <https://github.com/beetbox/beets/issues/3771>.
-         ;; Disable the faulty test as the fix is unclear.
-         (add-after 'unpack 'disable-failing-tests
-           (lambda _
-             (substitute* "test/test_mediafile.py"
-               (("def test_read_audio_properties") "def _test_read_audio_properties"))
-             #t))
          (add-after 'unpack 'set-HOME
            (lambda _
              (setenv "HOME" (string-append (getcwd) "/tmp"))
              #t))
          (replace 'check
-           (lambda _
-             (invoke "nosetests" "-v")))
-         ;; Wrap the executable, so it can find python-gi (aka pygobject) and
-         ;; gstreamer plugins.
+           (lambda* (#:key tests? #:allow-other-keys)
+             (when tests?
+               (invoke "pytest" "-v" "test"))))
+         ;; Wrap the executable, so it can find python-gi (aka
+         ;; pygobject) and gstreamer plugins.
          (add-after 'wrap 'wrap-typelib
            (lambda* (#:key outputs #:allow-other-keys)
              (let ((prog (string-append (assoc-ref outputs "out")
@@ -3825,112 +3795,68 @@ websites such as Libre.fm.")
                  `("GI_TYPELIB_PATH" ":" prefix (,types)))
                #t))))))
     (native-inputs
-     `(("python-beautifulsoup4" ,python-beautifulsoup4)
+     `(("gobject-introspection" ,gobject-introspection)
        ("python-flask" ,python-flask)
        ("python-mock" ,python-mock)
-       ("python-mpd2" ,python-mpd2)
-       ("python-nose" ,python-nose)
-       ("python-pathlib" ,python-pathlib)
-       ("python-pyxdg" ,python-pyxdg)
-       ("python-pylast" ,python-pylast)
-       ("python-rarfile" ,python-rarfile)
+       ("python-py7zr" ,python-py7zr)
+       ("python-pytest" ,python-pytest-6)
        ("python-responses" ,python-responses)))
-    ;; TODO: Install optional plugins and dependencies.
     (inputs
-     `(("python-discogs-client" ,python-discogs-client)
+     `(("bash-minimal" ,bash-minimal)
+       ("gst-plugins-base" ,gst-plugins-base)
+       ("gst-plugins-good" ,gst-plugins-good)
+       ("gstreamer" ,gstreamer)
+       ("python-confuse" ,python-confuse)
        ("python-jellyfish" ,python-jellyfish)
+       ("python-mediafile" ,python-mediafile)
        ("python-munkres" ,python-munkres)
        ("python-musicbrainzngs" ,python-musicbrainzngs)
-       ("python-mutagen" ,python-mutagen)
-       ("python-pyacoustid" ,python-pyacoustid)
        ("python-pyyaml" ,python-pyyaml)
+       ("python-six" ,python-six)
        ("python-unidecode" ,python-unidecode)
-       ;; For plugin replaygain.
-       ("python-pygobject" ,python-pygobject)
-       ("gobject-introspection" ,gobject-introspection)
-       ("gst-plugins-base" ,gst-plugins-base)
-       ("gst-plugins-good" ,gst-plugins-good)
-       ("gstreamer" ,gstreamer)))
+       ;; Optional dependencies for plugins. Some of these are also required by tests.
+       ("python-beautifulsoup4" ,python-beautifulsoup4) ; For lyrics.
+       ("python-discogs-client" ,python-discogs-client) ; For discogs.
+       ("python-mpd2" ,python-mpd2) ; For mpdstats.
+       ("python-mutagen" ,python-mutagen) ; For scrub.
+       ("python-langdetect" ,python-langdetect) ; For lyrics.
+       ("python-pillow" ,python-pillow) ; For fetchart, embedart, thumbnails.
+       ("python-pyacoustid" ,python-pyacoustid) ; For chroma.
+       ("python-pygobject" ,python-pygobject) ; For bpd, replaygain.
+       ("python-pylast" ,python-pylast) ; For lastgenre, lastimport.
+       ("python-pyxdg" ,python-pyxdg) ; For thumbnails.
+       ("python-rarfile" ,python-rarfile) ; For import.
+       ("python-reflink" ,python-reflink) ; For reflink.
+       ("python-requests" ,python-requests)
+       ("python-requests-oauthlib" ,python-requests-oauthlib))) ; For beatport.
     (home-page "https://beets.io")
     (synopsis "Music organizer")
-    (description "The purpose of beets is to get your music collection right
-    once and for all.  It catalogs your collection, automatically improving its
-    metadata as it goes using the MusicBrainz database.  Then it provides a variety
-    of tools for manipulating and accessing your music.")
+    (description "The purpose of beets is to get your music collection
+right once and for all.  It catalogs your collection, automatically
+improving its metadata as it goes using the MusicBrainz database.
+Then it provides a variety of tools for manipulating and accessing
+your music.")
     (license license:expat)))
 
 (define-public beets-next
-  (let ((commit "04ea754d00e2873ae9aa2d9e07c5cefd790eaee2")
-        (revision "1"))
-    (package
-      (inherit beets)
-      (name "beets-next")
-      (version (git-version (package-version beets) revision commit))
-      (source (origin
-                (method git-fetch)
-                (uri (git-reference
-                      (url "https://github.com/beetbox/beets")
-                      (commit commit)))
-                (file-name (git-file-name "beets" version))
-                (sha256
-                 (base32
-                  "092a9sss2shhcjmpgbwvscv8brpm5970i5hddkhi81xcff3bg1h4"))))
-      (arguments
-       `(#:phases
-         (modify-phases %standard-phases
-           ;; XXX: unclear why this fails
-           (add-after 'unpack 'disable-failing-tests
-             (lambda _
-               (substitute* "test/test_zero.py"
-                 (("def test_album_art") "def _test_album_art"))
-               #t))
-           (add-after 'unpack 'set-HOME
-             (lambda _
-               (setenv "HOME" (string-append (getcwd) "/tmp"))
-               #t))
-           (replace 'check
-             (lambda _
-               ;; Resources must be writable.
-               (for-each make-file-writable
-                         (find-files "test/rsrc" "."))
-               (invoke "nosetests" "-v")))
-           ;; Wrap the executable, so it can find python-gi (aka pygobject) and
-           ;; gstreamer plugins.
-           (add-after 'wrap 'wrap-typelib
-             (lambda* (#:key outputs #:allow-other-keys)
-               (let ((prog (string-append (assoc-ref outputs "out")
-                                          "/bin/beet"))
-                     (plugins (getenv "GST_PLUGIN_SYSTEM_PATH"))
-                     (types (getenv "GI_TYPELIB_PATH")))
-                 (wrap-program prog
-                   `("GST_PLUGIN_SYSTEM_PATH" ":" prefix (,plugins))
-                   `("GI_TYPELIB_PATH" ":" prefix (,types)))
-                 #t))))))
-      (inputs
-       `(("python-confuse" ,python-confuse)
-         ("python-mediafile" ,python-mediafile)
-         ("python-reflink" ,python-reflink)
-         ("python-requests-oauthlib" ,python-requests-oauthlib)
-         ("opusfile" ,opusfile)
-         ,@(package-inputs beets))))))
+  (deprecated-package "beets-next" beets))
 
 (define-public beets-bandcamp
   (package
     (name "beets-bandcamp")
-    (version "0.1.3")
+    (version "0.1.4")
     (source (origin
               (method url-fetch)
               (uri (pypi-uri "beets-bandcamp" version))
               (sha256
                (base32
-                "04awg0zdhhg5h510fc1p3qkvr2l1qm6nf85hlr9z8im8a7xlka0i"))))
+                "0dwbdkrb9c0ppzm5s78h47ndpr88cw1k0z8fgfhkl706wazx2ddg"))))
     (build-system python-build-system)
     (arguments '(#:tests? #f))          ; there are no tests
     (propagated-inputs
      `(("beets" ,beets)
-       ("python-isodate" ,python-isodate)))
-    (inputs
-     `(("python-beautifulsoup4" ,python-beautifulsoup4)
+       ("python-isodate" ,python-isodate)
+       ("python-beautifulsoup4" ,python-beautifulsoup4)
        ("python-requests" ,python-requests)
        ("python-six" ,python-six)))
     (home-page "https://github.com/unrblt/beets-bandcamp")
@@ -5080,7 +5006,7 @@ studio.")
 (define-public gsequencer
   (package
     (name "gsequencer")
-    (version "3.8.13")
+    (version "3.10.18")
     (source
      (origin
        (method git-fetch)
@@ -5089,7 +5015,7 @@ studio.")
              (commit version)))
        (file-name (git-file-name name version))
        (sha256
-        (base32 "1gwy7fhbxgrd5n6afq1hnxc6p873wsh4qs63yhkkdfzyl7s412z4"))))
+        (base32 "126kbvdkxy82mmkl19qhp9k6iz5xclar06chbj7lf580x96c899c"))))
     (build-system glib-or-gtk-build-system)
     (arguments
      `(#:phases
@@ -6307,7 +6233,7 @@ Soul Force), MVerb, Nekobi, and ProM.")
 (define-public avldrums-lv2
   (package
     (name "avldrums-lv2")
-    (version "0.4.1")
+    (version "0.4.2")
     (source
      (origin
        (method git-fetch)
@@ -6319,7 +6245,7 @@ Soul Force), MVerb, Nekobi, and ProM.")
              (recursive? #t)))
        (file-name (git-file-name name version))
        (sha256
-        (base32 "1vwdp3d8qzd493qa99ddya7iql67bbfxmbcl8hk96lxif2lhmyws"))))
+        (base32 "14gka5g7va30gm1hn0cas4vvb8s764rfvzcxm67ww86hf54cpnig"))))
     (build-system gnu-build-system)
     (arguments
      `(#:tests? #f                      ; no "check" target
@@ -6327,10 +6253,10 @@ Soul Force), MVerb, Nekobi, and ProM.")
        (list (string-append "PREFIX=" (assoc-ref %outputs "out")))
        #:phases
        (modify-phases %standard-phases
+         (delete 'configure)            ; no configure script
          (add-before 'build 'set-CC-variable
            (lambda _
-             (setenv "CC" "gcc") #t))
-         (delete 'configure))))
+             (setenv "CC" "gcc"))))))
     (inputs
      `(("cairo" ,cairo)
        ("dssi" ,dssi)
@@ -6426,7 +6352,6 @@ and as an LV2 plugin.")
    (build-system meson-build-system)
    (arguments
     `(#:glib-or-gtk? #t
-      #:meson ,meson-0.55
       #:configure-flags
       `("-Dtests=true"
         "-Dmanpage=true"
@@ -6899,7 +6824,7 @@ It is provided as an LV2 plugin and as a standalone Jack application.")
                (substitute* (string-append bin "a2j")
                  (("a2j_control") (string-append bin "a2j_control")))
                (wrap-program (string-append bin "a2j_control")
-                `("PYTHONPATH" prefix (,(getenv "PYTHONPATH"))))
+                `("PYTHONPATH" prefix (,(getenv "GUIX_PYTHONPATH"))))
                #t))))))
     (build-system meson-build-system)
     (inputs