From c80315946e885a523f74d6a66ca7d7fa0682d6c2 Mon Sep 17 00:00:00 2001 From: Grant Shangreaux Date: Sun, 10 Jan 2021 20:30:35 -0600 Subject: Add: emms-tracktag wrapper for the audiotools program http://audiotools.sourceforge.net/ provides a tool `tracktag` which handles writing tags for several different audio formats, including Opus. this patch provides a very basic wrapper to interface between EMMS track info and tracktag metadata. It also configures emms-tag-editor.el to use it for writing tags to Opus files. Add: test.sh and test/test-all.el Basic setup to run ert tests from the terminal using Emacs in batch mode. This should load up only ERT, the tests in the test/ directory and their dependencies. Add: opus extension to emms-libtag-known-extensions libtag works as a reader for opus files, this just ads the opus extension to the regexp list. --- emms-info-libtag.el | 2 +- emms-tag-editor.el | 4 +- emms-tracktag.el | 71 +++++++++++++++++++++++++++++++ test.sh | 3 ++ test/emms-tracktag-test.el | 101 +++++++++++++++++++++++++++++++++++++++++++++ test/test-all.el | 6 +++ 6 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 emms-tracktag.el create mode 100755 test.sh create mode 100644 test/emms-tracktag-test.el create mode 100644 test/test-all.el diff --git a/emms-info-libtag.el b/emms-info-libtag.el index fb9c5dd..9425a38 100644 --- a/emms-info-libtag.el +++ b/emms-info-libtag.el @@ -74,7 +74,7 @@ :type '(string)) (defcustom emms-info-libtag-known-extensions - (regexp-opt '("mp3" "mp4" "m4a" "ogg" "flac" "spx" "wma")) + (regexp-opt '("mp3" "mp4" "m4a" "ogg" "flac" "spx" "wma" "opus")) "Regexp of known extensions compatible with `emms-info-libtag-program-name'. Case is irrelevant." diff --git a/emms-tag-editor.el b/emms-tag-editor.el index 5b6e447..45c90f7 100644 --- a/emms-tag-editor.el +++ b/emms-tag-editor.el @@ -37,6 +37,7 @@ (require 'emms-info-mp3info) (require 'emms-playlist-mode) (require 'emms-mark) +(require 'emms-tracktag) (require 'format-spec) (require 'subr-x) @@ -138,7 +139,8 @@ See also `emms-tag-editor-default-parser'.") (info-performer . "--TOPE") (info-date . "--TDAT"))) ("ogg" . emms-tag-editor-tag-ogg) - ("flac" . emms-tag-editor-tag-flac)) + ("flac" . emms-tag-editor-tag-flac) + ("opus" . emms-tracktag-file)) "An alist used when committing changes to tags in files. If the external program sets tags by command line options one-by-one, then the list should like: diff --git a/emms-tracktag.el b/emms-tracktag.el new file mode 100644 index 0000000..0b8b660 --- /dev/null +++ b/emms-tracktag.el @@ -0,0 +1,71 @@ +;;; emms-tracktag.el --- EMMS interface for audiotools tracktag -*- lexical-binding: t; -*- + +;; Copyright (C) 2021 Grant Shoshin Shangreaux + +;; Author: Grant Shoshin Shangreaux +;; Keywords: + +;; 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, see . + +;;; Commentary: + +;; Provides a wrapper for audiotools tracktag executable +;; http://audiotools.sourceforge.net/tracktag.html +;; Given an EMMS TRACK structure, it will map the emms-info fields onto +;; arguments for tracktag. Then it calls the tracktag process to write the +;; info as metadata tags on the track's associated file. + +;;; Code: + +(require 'emms) + +(defvar emms-info-tracktag--info-fields + '((info-album . album) + (info-artist . artist) + (info-composer . composer) + (info-performer . performer) + (info-year . year) + (info-date . year) + (info-tracknumber . number) + (info-discnumber . album-number) + (info-note . comment) + (info-title . name)) + "An alist mapping info-* fields to tracktag fields.") + +(defun emms-tracktag--map-track-info (track) + (seq-filter (lambda (cell) (cdr cell)) + (mapcar (lambda (pair) + (cons (cdr pair) (emms-track-get track (car pair)))) + emms-info-tracktag--info-fields))) + +(defun emms-tracktag--build-args (track) + (flatten-list + (append (mapcar (lambda (pair) + (let ((tag (car pair)) (value (cdr pair))) + (when value + (if (string-equal value "") (concat "--remove-" (format "%s" tag)) + (concat "--" (format "%s" tag) "=" value))))) + (emms-tracktag--map-track-info track)) + (list (emms-track-name track))))) + +(defun emms-tracktag-file (track) + (apply #'call-process + "tracktag" nil + (get-buffer-create emms-tag-editor-log-buffer) + nil + "-Vdebug" + (emms-tracktag--build-args track))) + +(provide 'emms-tracktag) +;;; emms-tracktag.el ends here diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..50547b1 --- /dev/null +++ b/test.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +emacs -Q --batch --directory="." -l ert -l test/test-all.el -f ert-run-tests-batch-and-exit diff --git a/test/emms-tracktag-test.el b/test/emms-tracktag-test.el new file mode 100644 index 0000000..9b66d5e --- /dev/null +++ b/test/emms-tracktag-test.el @@ -0,0 +1,101 @@ +;; emms-tracktag-test.el --- Unit tests for emms-tracktag module -*- lexical-binding: t; -*- + +;; Copyright (C) 2021 Grant Shoshin Shangreaux + +;; Author: Grant Shoshin Shangreaux +;; Keywords: + +;; 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, see . + +;;; Commentary: + +;; Tests for emms-tracktag.el + +;;; Code: + +(require 'emms) +(require 'emms-tracktag) + +(ert-deftest emms-tracktag--map-track-info-test () + "Ensure mapping of emms info to tracktag fields is correct." + (let ((track '(*track* + (type . file) (name . "foo") + (info-album . "The Sounds of the Sounds of Science") + (info-artist . "Yo La Tengo") + (info-title . "Sea Urchins") + (info-date . "2020") + (info-tracknumber . "1"))) + (track2 '(*track* + (info-composer . "Ira Kaplan, Georgia Hubley, James Mcnew") + (info-performer . "Yo La Tengo") + (info-year . "2002") + (info-discnumber . "1") + (info-note . "new soundtrack to an old film")))) + (should (seq-set-equal-p + '((album . "The Sounds of the Sounds of Science") + (artist . "Yo La Tengo") + (name . "Sea Urchins") + (year . "2020") + (number . "1")) + (emms-tracktag--map-track-info track))) + (should (seq-set-equal-p + '((composer . "Ira Kaplan, Georgia Hubley, James Mcnew") + (performer . "Yo La Tengo") + (year . "2002") + (album-number . "1") + (comment . "new soundtrack to an old film")) + (emms-tracktag--map-track-info track2))))) + +(ert-deftest emms-tracktag--build-args-test () + "Ensure args for tracktag are properly formed." + (let ((track '(*track* + (type . file) (name . "foo.flac") + (info-album . "The Sounds of the Sounds of Science") + (info-artist . "Yo La Tengo") + (info-title . "Sea Urchins") + (info-date . "2020") + (info-tracknumber . "1") + (info-composer . "Ira Kaplan, Georgia Hubley, James Mcnew") + (info-performer . "Yo La Tengo") + (info-discnumber . "1") + (info-note . "new soundtrack to an old film")))) + (should (seq-set-equal-p + '("--album=The Sounds of the Sounds of Science" + "--artist=Yo La Tengo" + "--name=Sea Urchins" + "--year=2020" + "--number=1" + "--composer=Ira Kaplan, Georgia Hubley, James Mcnew" + "--performer=Yo La Tengo" + "--album-number=1" + "--comment=new soundtrack to an old film" + "foo.flac") + (emms-tracktag--build-args track))) + (let ((track-with-empty-strings (copy-alist track))) + (setcdr (assq 'info-title track-with-empty-strings) "") + (setcdr (assq 'info-note track-with-empty-strings) "") + (should (seq-set-equal-p + '("--album=The Sounds of the Sounds of Science" + "--artist=Yo La Tengo" + "--year=2020" + "--number=1" + "--composer=Ira Kaplan, Georgia Hubley, James Mcnew" + "--performer=Yo La Tengo" + "--album-number=1" + "--remove-comment" + "--remove-name" + "foo.flac") + (emms-tracktag--build-args track-with-empty-strings)))))) + +;;; emms-tracktag-test.el ends here diff --git a/test/test-all.el b/test/test-all.el new file mode 100644 index 0000000..36f00c7 --- /dev/null +++ b/test/test-all.el @@ -0,0 +1,6 @@ +;; maybe not needed, but ensures tests run against the latest changes +(byte-recompile-directory ".") + +(mapc #'load + (mapcar (lambda (f) (file-truename (concat "test/" f))) + (seq-filter (lambda (f) (string-match "[^.#]+\\test.el$" f)) (directory-files (file-truename "./test"))))) -- cgit v1.2.3