[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Any appetite for patches for EMMS support for SNES SPC files?

From: Warren Wilkinson
Subject: Re: Any appetite for patches for EMMS support for SNES SPC files?
Date: Thu, 27 Jul 2023 21:18:44 -0600
User-agent: Gnus/5.13 (Gnus v5.13)

> Yoni Rabkin <yoni@rabkins.net> writes:
> Please write back when you get the OK from the copyright clerk.

Will do!

> mpv also uses `emms-player-base-format-list', but using it is
> optional. In any case, there is no problem with adding spc to that
> list.

I downloaded and tested mpv: mpv can also playback .spc files.

> As for the rest, can you please split it out to a separate file such as
> "emms-info-native-spc" or "emms-info-native-id666" or similar? That will
> scale better as we add more native info methods.

I've split it into emms-info-native-spc. I choose "-spc" over "-id666"
because that's probably easier for a person trying to find the relevant

diff --git a/emms-info-native-spc.el b/emms-info-native-spc.el
new file mode 100644
index 0000000..ebfde2c
--- /dev/null
+++ b/emms-info-native-spc.el
@@ -0,0 +1,95 @@
+;;; emms-info-native-spc.el --- Native Emacs Lisp info method for EMMS -*- 
lexical-binding: t; -*-
+;; Copyright (C) 2023-2024 Free Software Foundation, Inc.
+;; Author: Warren Wilkinson <warrenwilkinson@gmail.com>
+;; This file is part of EMMS.
+;; EMMS 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, or (at your option)
+;; any later version.
+;; EMMS 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 EMMS; see the file COPYING. If not, write to the Free
+;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+;; MA 02110-1301, USA.
+;;; Commentary:
+;; This file provides a native emms-info-method for SPC files. (well,
+;; actually the id666 tag embedded inside them). "Native" means a pure
+;; Emacs Lisp implementation instead of one relying on external tools
+;; or libraries.
+;;; Code:
+(require 'bindat)
+(defconst emms-info-native-spc--id666-magic-array
+  [#x53 #x4e #x45 #x53 #x2d #x53 #x50#x43 #x37 #x30 #x30 #x20 #x53 #x6f #x75 
#x6e #x64 #x20 #x46 #x69 #x6c #x65 #x20 #x44 #x61 #x74 #x61 #x20 #x76 #x30 #x2e 
#x33 #x30]
+  "id666 header magic pattern `SNES-SPC700 Sound File Data v0.30'")
+(defconst emms-info-native-spc--id666-header-bindat-spec
+  '((file-identifier vec 33)
+    (eval (unless (equal last emms-info-native-spc--id666-magic-array)
+            (error "id666 framing mismatch: expected `%s', got `%s'"
+                   emms-info-native-spc--id666-magic-array
+                   last)))
+    (unused u16)
+    (has-id666 u8)
+    (revision u8)
+    (pc-reg u16)
+    (a-reg u8)
+    (x-reg u8)
+    (y-reg u8)
+    (psw-reg u8)
+    (sp-reg u8)
+    (res-reg u16)
+    (song-title strz 32)
+    (game-title strz 32)
+    (dumper strz 16)
+    (comment strz 32)
+    (date strz 11)
+    (fadeout vec 3)
+    (fadeout-length vec 5)
+    (artist strz 32))
+  "id666 header specification.
+- URL `https://ocremix.org/info/SPC_Format_Specification'
+- URL `https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html'")
+(defun emms-info-native-spc--decode-id666-header (filename)
+  "Read and decode id666 header from FILENAME."
+  (with-temp-buffer
+    (set-buffer-multibyte nil)
+    (insert-file-contents-literally filename nil 0 210)
+    (bindat-unpack emms-info-native-spc--id666-header-bindat-spec
+                   (buffer-string))))
+(defun emms-info-native-spc--decode-id666 (filename)
+  "Read and decode id666 metadata from FILENAME.
+Return metadata in a list of (FIELD . VALUE) cons cells, or nil
+in case of errors or if there were no known fields in FILENAME."
+  (condition-case nil
+      (let ((header (emms-info-native-spc--decode-id666-header filename)))
+       (when (= 26 (bindat-get-field header 'has-id666))
+         (list
+          (cons 'info-title (bindat-get-field header 'song-title))
+          (cons 'info-album (bindat-get-field header 'game-title))
+          (cons 'info-artist (bindat-get-field header 'artist))
+          (cons 'info-composer (bindat-get-field header 'artist))
+          (cons 'info-note (bindat-get-field header 'comment)))))
+    (error nil)))
+(provide 'emms-info-native-spc)
+;;; emms-info-native-spc.el ends here
diff --git a/emms-info-native.el b/emms-info-native.el
index 3e3e2d4..6c8bfff 100644
--- a/emms-info-native.el
+++ b/emms-info-native.el
@@ -51,6 +51,10 @@
 ;;   encryption are not supported.  Based on id3v2 Informal Standards,
 ;;   see URL `https://id3.org'.
+;; - SPC files with extension `.spc' and id666 tags.  This is an audio
+;;   file based on a memory dump from an SPC700, a special audio chip
+;;   found within Super Nintendos.
 ;; Format detection is based solely on filename extension, which is
 ;; matched case-insensitively.
@@ -59,6 +63,7 @@
 (require 'bindat)
 (require 'cl-lib)
 (require 'emms-info)
+(require 'emms-info-native-spc)
 (require 'seq)
 (require 'subr-x)
@@ -954,6 +959,8 @@ strings."
            (emms-info-native--decode-flac-comments filename))
           ((eq stream-type 'mp3)
            (emms-info-native--decode-id3v2 filename))
+         ((eq stream-type 'spc)
+          (emms-info-native-spc--decode-id666 filename))
           (t nil))))
 (defun emms-info-native--find-stream-type (filename)
@@ -967,6 +974,7 @@ Return one of symbols `vorbis', `opus', `flac', or `mp3'."
           ((string-match ".opus$" filename) 'opus)
           ((string-match ".flac$" filename) 'flac)
           ((string-match ".mp3$" filename) 'mp3)
+         ((string-match ".spc$" filename) 'spc)
           (t nil))))
 (provide 'emms-info-native)
diff --git a/emms.el b/emms.el
index 8581dfe..e003c72 100644
--- a/emms.el
+++ b/emms.el
@@ -376,7 +376,7 @@ Point will not be restored afterward."
   '("ogg" "mp3" "wav" "mpg" "mpeg" "wmv" "wma"
     "mov" "avi" "divx" "ogm" "ogv" "asf" "mkv"
     "rm" "rmvb" "mp4" "flac" "vob" "m4a" "ape"
-    "flv" "webm" "aif" "opus")
+    "flv" "webm" "aif" "opus" "spc")
   "A list of common formats which player definitions can use.")

reply via email to

[Prev in Thread] Current Thread [Next in Thread]