fordon_greeman / voidfiles

Branch: main
Switch branches/tags
main
theidioticdev add emacs 2079ec5 1d ago
121 lines · 4 KB Raw Blame History
1 ;;; emms-info-native-spc.el --- EMMS info functions for SPC files -*- lexical-binding: t; -*-
2
3 ;; Copyright (C) 2023 Free Software Foundation, Inc.
4
5 ;; Author: Warren Wilkinson <warrenwilkinson@gmail.com>
6
7 ;; This file is part of EMMS.
8
9 ;; EMMS is free software; you can redistribute it and/or modify it
10 ;; under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; any later version.
13
14 ;; EMMS is distributed in the hope that it will be useful, but WITHOUT
15 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 ;; License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with EMMS; see the file COPYING. If not, write to the Free
21 ;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 ;; MA 02110-1301, USA.
23
24 ;;; Commentary:
25
26 ;; This file provides a native emms-info-method for SPC files. (well,
27 ;; actually the ID666 tag embedded inside them). "Native" means a
28 ;; pure Emacs Lisp implementation instead of one relying on external
29 ;; tools or libraries.
30
31 ;;; Code:
32
33 (require 'bindat)
34
35 (defconst emms-info-native-spc--id666-magic-pattern
36 "SNES-SPC700 Sound File Data v0.30"
37 "ID666 header magic pattern.")
38
39 (defconst emms-info-native-spc--id666-header-bindat-spec
40 (if (eval-when-compile (fboundp 'bindat-type))
41 (bindat-type
42 (file-identifier str 33)
43 (_ unit (unless (equal file-identifier
44 emms-info-native-spc--id666-magic-pattern)
45 (error "ID666 framing mismatch: expected `%s', got `%s'"
46 emms-info-native-spc--id666-magic-pattern
47 file-identifier)))
48 (unused uint 16)
49 (has-id666 u8)
50 (revision u8)
51 (pc-reg uint 16)
52 (a-reg u8)
53 (x-reg u8)
54 (y-reg u8)
55 (psw-reg u8)
56 (sp-reg u8)
57 (res-reg uint 16)
58 (song-title strz 32)
59 (game-title strz 32)
60 (dumper strz 16)
61 (comment strz 32)
62 (date strz 11)
63 (fadeout vec 3)
64 (fadeout-length vec 5)
65 (artist strz 32))
66 '((file-identifier str 33)
67 (eval (unless (equal last emms-info-native-spc--id666-magic-pattern)
68 (error "ID666 framing mismatch: expected `%s', got `%s'"
69 emms-info-native-spc--id666-magic-pattern
70 last)))
71 (unused u16)
72 (has-id666 u8)
73 (revision u8)
74 (pc-reg u16)
75 (a-reg u8)
76 (x-reg u8)
77 (y-reg u8)
78 (psw-reg u8)
79 (sp-reg u8)
80 (res-reg u16)
81 (song-title strz 32)
82 (game-title strz 32)
83 (dumper strz 16)
84 (comment strz 32)
85 (date strz 11)
86 (fadeout vec 3)
87 (fadeout-length vec 5)
88 (artist strz 32)))
89 "ID666 header specification.
90
91 Sources:
92
93 - URL `https://ocremix.org/info/SPC_Format_Specification'
94 - URL `https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html'")
95
96 (defun emms-info-native-spc--decode-id666-header (filename)
97 "Read and decode ID666 header from FILENAME."
98 (with-temp-buffer
99 (set-buffer-multibyte nil)
100 (insert-file-contents-literally filename nil 0 210)
101 (bindat-unpack emms-info-native-spc--id666-header-bindat-spec
102 (buffer-string))))
103
104 (defun emms-info-native-spc-decode-id666 (filename)
105 "Read and decode ID666 metadata from FILENAME.
106 Return metadata in a list of (FIELD . VALUE) cons cells, or nil
107 in case of errors or if there were no known fields in FILENAME."
108 (condition-case nil
109 (let ((header (emms-info-native-spc--decode-id666-header filename)))
110 (when (= 26 (bindat-get-field header 'has-id666))
111 (list
112 (cons 'info-title (bindat-get-field header 'song-title))
113 (cons 'info-album (bindat-get-field header 'game-title))
114 (cons 'info-artist (bindat-get-field header 'artist))
115 (cons 'info-composer (bindat-get-field header 'artist))
116 (cons 'info-note (bindat-get-field header 'comment)))))
117 (error nil)))
118
119 (provide 'emms-info-native-spc)
120
121 ;;; emms-info-native-spc.el ends here