2020-06-08 03:29:51 +03:00
|
|
|
|
package id3
|
|
|
|
|
|
|
|
|
|
import (
|
2021-08-17 13:06:32 +03:00
|
|
|
|
"github.com/wader/fq/format"
|
|
|
|
|
"github.com/wader/fq/pkg/decode"
|
2022-07-16 19:39:57 +03:00
|
|
|
|
"github.com/wader/fq/pkg/interp"
|
2021-12-02 00:48:25 +03:00
|
|
|
|
"github.com/wader/fq/pkg/scalar"
|
2020-06-08 03:29:51 +03:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// TODO: comment 28 long, zero byte, track number
|
|
|
|
|
|
|
|
|
|
func init() {
|
2022-07-16 19:39:57 +03:00
|
|
|
|
interp.RegisterFormat(decode.Format{
|
2020-06-08 03:29:51 +03:00
|
|
|
|
Name: format.ID3V1,
|
|
|
|
|
Description: "ID3v1 metadata",
|
|
|
|
|
DecodeFn: id3v1Decode,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Decode ID3v1 tag
|
2023-02-18 23:10:48 +03:00
|
|
|
|
func id3v1Decode(d *decode.D) any {
|
2021-11-05 17:04:26 +03:00
|
|
|
|
d.AssertAtLeastBitsLeft(128 * 8)
|
2022-09-30 14:58:23 +03:00
|
|
|
|
d.FieldUTF8("magic", 3, d.StrAssert("TAG"))
|
2023-03-10 03:14:53 +03:00
|
|
|
|
if d.PeekUintBits(8) == uint64('+') {
|
2021-11-17 18:26:13 +03:00
|
|
|
|
d.Errorf("looks like id3v11")
|
2020-06-08 03:29:51 +03:00
|
|
|
|
}
|
2021-11-17 18:13:10 +03:00
|
|
|
|
d.FieldUTF8NullFixedLen("song_name", 30)
|
|
|
|
|
d.FieldUTF8NullFixedLen("artist", 30)
|
|
|
|
|
d.FieldUTF8NullFixedLen("album_name", 30)
|
|
|
|
|
d.FieldUTF8NullFixedLen("year", 4)
|
|
|
|
|
d.FieldUTF8NullFixedLen("comment", 30)
|
2020-06-08 03:29:51 +03:00
|
|
|
|
// from https://en.wikipedia.org/wiki/List_of_ID3v1_Genres
|
2022-09-30 14:58:23 +03:00
|
|
|
|
d.FieldU8("genre", scalar.UintMap{
|
2022-04-05 14:57:55 +03:00
|
|
|
|
0: {Sym: "blues", Description: "Blues"},
|
|
|
|
|
1: {Sym: "classic_rock", Description: "Classic Rock"},
|
|
|
|
|
2: {Sym: "country", Description: "Country"},
|
|
|
|
|
3: {Sym: "dance", Description: "Dance"},
|
|
|
|
|
4: {Sym: "disco", Description: "Disco"},
|
|
|
|
|
5: {Sym: "funk", Description: "Funk"},
|
|
|
|
|
6: {Sym: "grunge", Description: "Grunge"},
|
|
|
|
|
7: {Sym: "hiphop", Description: "Hip-Hop"},
|
|
|
|
|
8: {Sym: "jazz", Description: "Jazz"},
|
|
|
|
|
9: {Sym: "metal", Description: "Metal"},
|
2022-05-05 20:38:31 +03:00
|
|
|
|
10: {Sym: "new_age", Description: "New Age"},
|
2022-04-05 14:57:55 +03:00
|
|
|
|
11: {Sym: "oldies", Description: "Oldies"},
|
|
|
|
|
12: {Sym: "other", Description: "Other"},
|
|
|
|
|
13: {Sym: "pop", Description: "Pop"},
|
|
|
|
|
14: {Sym: "rhythm_and_blues", Description: "Rhythm and Blues"},
|
|
|
|
|
15: {Sym: "rap", Description: "Rap"},
|
|
|
|
|
16: {Sym: "reggae", Description: "Reggae"},
|
|
|
|
|
17: {Sym: "rock", Description: "Rock"},
|
|
|
|
|
18: {Sym: "techno", Description: "Techno"},
|
|
|
|
|
19: {Sym: "industrial", Description: "Industrial"},
|
|
|
|
|
20: {Sym: "alternative", Description: "Alternative"},
|
|
|
|
|
21: {Sym: "ska", Description: "Ska"},
|
|
|
|
|
22: {Sym: "death_metal", Description: "Death Metal"},
|
|
|
|
|
23: {Sym: "pranks", Description: "Pranks"},
|
|
|
|
|
24: {Sym: "soundtrack", Description: "Soundtrack"},
|
|
|
|
|
25: {Sym: "euro_techno", Description: "Euro-Techno"},
|
|
|
|
|
26: {Sym: "ambient", Description: "Ambient"},
|
|
|
|
|
27: {Sym: "triphop", Description: "Trip-Hop"},
|
|
|
|
|
28: {Sym: "vocal", Description: "Vocal"},
|
|
|
|
|
29: {Sym: "jazz_funk", Description: "Jazz & Funk"},
|
|
|
|
|
30: {Sym: "fusion", Description: "Fusion"},
|
|
|
|
|
31: {Sym: "trance", Description: "Trance"},
|
|
|
|
|
32: {Sym: "classical", Description: "Classical"},
|
|
|
|
|
33: {Sym: "instrumental", Description: "Instrumental"},
|
|
|
|
|
34: {Sym: "acid", Description: "Acid"},
|
|
|
|
|
35: {Sym: "house", Description: "House"},
|
|
|
|
|
36: {Sym: "game", Description: "Game"},
|
|
|
|
|
37: {Sym: "sound_clip", Description: "Sound clip"},
|
|
|
|
|
38: {Sym: "gospel", Description: "Gospel"},
|
|
|
|
|
39: {Sym: "noise", Description: "Noise"},
|
|
|
|
|
40: {Sym: "alternative_rock", Description: "Alternative Rock"},
|
|
|
|
|
41: {Sym: "bass", Description: "Bass"},
|
|
|
|
|
42: {Sym: "soul", Description: "Soul"},
|
|
|
|
|
43: {Sym: "punk", Description: "Punk"},
|
|
|
|
|
44: {Sym: "space", Description: "Space"},
|
|
|
|
|
45: {Sym: "meditative", Description: "Meditative"},
|
|
|
|
|
46: {Sym: "instrumental_pop", Description: "Instrumental Pop"},
|
|
|
|
|
47: {Sym: "instrumental_rock", Description: "Instrumental Rock"},
|
|
|
|
|
48: {Sym: "ethnic", Description: "Ethnic"},
|
|
|
|
|
49: {Sym: "gothic", Description: "Gothic"},
|
|
|
|
|
50: {Sym: "darkwave", Description: "Darkwave"},
|
|
|
|
|
51: {Sym: "techno-industrial", Description: "Techno-Industrial"},
|
|
|
|
|
52: {Sym: "electronic", Description: "Electronic"},
|
|
|
|
|
53: {Sym: "pop-folk", Description: "Pop-Folk"},
|
|
|
|
|
54: {Sym: "eurodance", Description: "Eurodance"},
|
|
|
|
|
55: {Sym: "dream", Description: "Dream"},
|
2022-05-05 20:38:31 +03:00
|
|
|
|
56: {Sym: "southern_rock", Description: "Southern Rock"},
|
2022-04-05 14:57:55 +03:00
|
|
|
|
57: {Sym: "comedy", Description: "Comedy"},
|
|
|
|
|
58: {Sym: "cult", Description: "Cult"},
|
|
|
|
|
59: {Sym: "gangsta", Description: "Gangsta"},
|
2022-05-05 20:38:31 +03:00
|
|
|
|
60: {Sym: "top_40", Description: "Top 40"},
|
|
|
|
|
61: {Sym: "christian_rap", Description: "Christian Rap"},
|
|
|
|
|
62: {Sym: "pop_funk", Description: "Pop/Funk"},
|
|
|
|
|
63: {Sym: "jungle_music", Description: "Jungle music"},
|
|
|
|
|
64: {Sym: "native_us", Description: "Native US"},
|
2022-04-05 14:57:55 +03:00
|
|
|
|
65: {Sym: "cabaret", Description: "Cabaret"},
|
2022-05-05 20:38:31 +03:00
|
|
|
|
66: {Sym: "new_wave", Description: "New Wave"},
|
2022-04-05 14:57:55 +03:00
|
|
|
|
67: {Sym: "psychedelic", Description: "Psychedelic"},
|
|
|
|
|
68: {Sym: "rave", Description: "Rave"},
|
|
|
|
|
69: {Sym: "showtunes", Description: "Showtunes"},
|
|
|
|
|
70: {Sym: "trailer", Description: "Trailer"},
|
|
|
|
|
71: {Sym: "lo-fi", Description: "Lo-Fi"},
|
|
|
|
|
72: {Sym: "tribal", Description: "Tribal"},
|
|
|
|
|
73: {Sym: "acid_punk", Description: "Acid Punk"},
|
|
|
|
|
74: {Sym: "acid_jazz", Description: "Acid Jazz"},
|
|
|
|
|
75: {Sym: "polka", Description: "Polka"},
|
|
|
|
|
76: {Sym: "retro", Description: "Retro"},
|
|
|
|
|
77: {Sym: "musical", Description: "Musical"},
|
|
|
|
|
78: {Sym: "rock_n_roll", Description: "Rock ’n’ Roll"},
|
2022-05-05 20:38:31 +03:00
|
|
|
|
79: {Sym: "hard_rock", Description: "Hard Rock"},
|
2022-04-05 14:57:55 +03:00
|
|
|
|
80: {Sym: "folk", Description: "Folk"},
|
|
|
|
|
81: {Sym: "folk-rock", Description: "Folk-Rock"},
|
|
|
|
|
82: {Sym: "national_folk", Description: "National Folk"},
|
|
|
|
|
83: {Sym: "swing", Description: "Swing"},
|
|
|
|
|
84: {Sym: "fast_fusion", Description: "Fast Fusion"},
|
|
|
|
|
85: {Sym: "bebop", Description: "Bebop"},
|
|
|
|
|
86: {Sym: "latin", Description: "Latin"},
|
|
|
|
|
87: {Sym: "revival", Description: "Revival"},
|
|
|
|
|
88: {Sym: "celtic", Description: "Celtic"},
|
|
|
|
|
89: {Sym: "bluegrass", Description: "Bluegrass"},
|
|
|
|
|
90: {Sym: "avantgarde", Description: "Avantgarde"},
|
|
|
|
|
91: {Sym: "gothic_rock", Description: "Gothic Rock"},
|
|
|
|
|
92: {Sym: "progressive_rock", Description: "Progressive Rock"},
|
|
|
|
|
93: {Sym: "psychedelic_rock", Description: "Psychedelic Rock"},
|
2022-05-05 20:38:31 +03:00
|
|
|
|
94: {Sym: "symphonic_rock", Description: "Symphonic Rock"},
|
2022-04-05 14:57:55 +03:00
|
|
|
|
95: {Sym: "slow_rock", Description: "Slow Rock"},
|
2022-05-05 20:38:31 +03:00
|
|
|
|
96: {Sym: "big_band", Description: "Big Band"},
|
2022-04-05 14:57:55 +03:00
|
|
|
|
97: {Sym: "chorus", Description: "Chorus"},
|
|
|
|
|
98: {Sym: "easy_listening", Description: "Easy Listening"},
|
|
|
|
|
99: {Sym: "acoustic", Description: "Acoustic"},
|
|
|
|
|
100: {Sym: "humour", Description: "Humour"},
|
|
|
|
|
101: {Sym: "speech", Description: "Speech"},
|
|
|
|
|
102: {Sym: "chanson", Description: "Chanson"},
|
|
|
|
|
103: {Sym: "opera", Description: "Opera"},
|
|
|
|
|
104: {Sym: "chamber_music", Description: "Chamber Music"},
|
|
|
|
|
105: {Sym: "sonata", Description: "Sonata"},
|
|
|
|
|
106: {Sym: "symphony", Description: "Symphony"},
|
|
|
|
|
107: {Sym: "booty_bass", Description: "Booty Bass"},
|
|
|
|
|
108: {Sym: "primus", Description: "Primus"},
|
|
|
|
|
109: {Sym: "porn_groove", Description: "Porn Groove"},
|
|
|
|
|
110: {Sym: "satire", Description: "Satire"},
|
|
|
|
|
111: {Sym: "slow_jam", Description: "Slow Jam"},
|
|
|
|
|
112: {Sym: "club", Description: "Club"},
|
|
|
|
|
113: {Sym: "tango", Description: "Tango"},
|
|
|
|
|
114: {Sym: "samba", Description: "Samba"},
|
|
|
|
|
115: {Sym: "folklore", Description: "Folklore"},
|
|
|
|
|
116: {Sym: "ballad", Description: "Ballad"},
|
|
|
|
|
117: {Sym: "power_ballad", Description: "Power Ballad"},
|
|
|
|
|
118: {Sym: "rhythmic_soul", Description: "Rhythmic Soul"},
|
|
|
|
|
119: {Sym: "freestyle", Description: "Freestyle"},
|
|
|
|
|
120: {Sym: "duet", Description: "Duet"},
|
|
|
|
|
121: {Sym: "punk_rock", Description: "Punk Rock"},
|
|
|
|
|
122: {Sym: "drum_solo", Description: "Drum Solo"},
|
|
|
|
|
123: {Sym: "a_cappella", Description: "A cappella"},
|
|
|
|
|
124: {Sym: "euro_house", Description: "Euro-House"},
|
|
|
|
|
125: {Sym: "dance_hall", Description: "Dance Hall"},
|
|
|
|
|
126: {Sym: "goa_music", Description: "Goa music"},
|
|
|
|
|
127: {Sym: "drum_n_bass", Description: "Drum & Bass"},
|
|
|
|
|
128: {Sym: "club_house", Description: "Club-House"},
|
|
|
|
|
129: {Sym: "hardcore_techno", Description: "Hardcore Techno"},
|
|
|
|
|
130: {Sym: "terror", Description: "Terror"},
|
|
|
|
|
131: {Sym: "indie", Description: "Indie"},
|
|
|
|
|
132: {Sym: "britpop", Description: "BritPop"},
|
|
|
|
|
133: {Sym: "negerpunk", Description: "Negerpunk"},
|
|
|
|
|
134: {Sym: "polsk_punk", Description: "Polsk Punk"},
|
|
|
|
|
135: {Sym: "beat", Description: "Beat"},
|
|
|
|
|
136: {Sym: "christian_gangsta_rap", Description: "Christian Gangsta Rap"},
|
|
|
|
|
137: {Sym: "heavy_metal", Description: "Heavy Metal"},
|
|
|
|
|
138: {Sym: "black_metal", Description: "Black Metal"},
|
|
|
|
|
139: {Sym: "crossover", Description: "Crossover"},
|
|
|
|
|
140: {Sym: "contemporary_christian", Description: "Contemporary Christian"},
|
|
|
|
|
141: {Sym: "christian_rock", Description: "Christian Rock"},
|
|
|
|
|
142: {Sym: "merengue", Description: "Merengue"},
|
|
|
|
|
143: {Sym: "salsa", Description: "Salsa"},
|
|
|
|
|
144: {Sym: "thrash_metal", Description: "Thrash Metal"},
|
|
|
|
|
145: {Sym: "anime", Description: "Anime"},
|
|
|
|
|
146: {Sym: "jpop", Description: "Jpop"},
|
|
|
|
|
147: {Sym: "synthpop", Description: "Synthpop"},
|
|
|
|
|
148: {Sym: "abstract", Description: "Abstract"},
|
|
|
|
|
149: {Sym: "art_rock", Description: "Art Rock"},
|
|
|
|
|
150: {Sym: "baroque", Description: "Baroque"},
|
|
|
|
|
151: {Sym: "bhangra", Description: "Bhangra"},
|
|
|
|
|
152: {Sym: "big_beat", Description: "Big beat"},
|
|
|
|
|
153: {Sym: "breakbeat", Description: "Breakbeat"},
|
|
|
|
|
154: {Sym: "chillout", Description: "Chillout"},
|
|
|
|
|
155: {Sym: "downtempo", Description: "Downtempo"},
|
|
|
|
|
156: {Sym: "dub", Description: "Dub"},
|
|
|
|
|
157: {Sym: "ebm", Description: "EBM"},
|
|
|
|
|
158: {Sym: "eclectic", Description: "Eclectic"},
|
|
|
|
|
159: {Sym: "electro", Description: "Electro"},
|
|
|
|
|
160: {Sym: "electroclash", Description: "Electroclash"},
|
|
|
|
|
161: {Sym: "emo", Description: "Emo"},
|
|
|
|
|
162: {Sym: "experimental", Description: "Experimental"},
|
|
|
|
|
163: {Sym: "garage", Description: "Garage"},
|
|
|
|
|
164: {Sym: "global", Description: "Global"},
|
|
|
|
|
165: {Sym: "idm", Description: "IDM"},
|
|
|
|
|
166: {Sym: "illbient", Description: "Illbient"},
|
|
|
|
|
167: {Sym: "industro_goth", Description: "Industro-Goth"},
|
|
|
|
|
168: {Sym: "jam_band", Description: "Jam Band"},
|
|
|
|
|
169: {Sym: "krautrock", Description: "Krautrock"},
|
|
|
|
|
170: {Sym: "leftfield", Description: "Leftfield"},
|
|
|
|
|
171: {Sym: "lounge", Description: "Lounge"},
|
|
|
|
|
172: {Sym: "math_rock", Description: "Math Rock"},
|
|
|
|
|
173: {Sym: "new_romantic", Description: "New Romantic"},
|
|
|
|
|
174: {Sym: "nu_breakz", Description: "Nu-Breakz"},
|
|
|
|
|
175: {Sym: "post_punk", Description: "Post-Punk"},
|
|
|
|
|
176: {Sym: "post_rock", Description: "Post-Rock"},
|
|
|
|
|
177: {Sym: "psytrance", Description: "Psytrance"},
|
|
|
|
|
178: {Sym: "shoegaze", Description: "Shoegaze"},
|
|
|
|
|
179: {Sym: "space_rock", Description: "Space Rock"},
|
|
|
|
|
180: {Sym: "trop_rock", Description: "Trop Rock"},
|
|
|
|
|
181: {Sym: "world_music", Description: "World Music"},
|
|
|
|
|
182: {Sym: "neoclassical", Description: "Neoclassical"},
|
|
|
|
|
183: {Sym: "audiobook", Description: "Audiobook"},
|
|
|
|
|
184: {Sym: "audio_theatre", Description: "Audio Theatre"},
|
|
|
|
|
185: {Sym: "neue_deutsche_welle", Description: "Neue Deutsche Welle"},
|
|
|
|
|
186: {Sym: "podcast", Description: "Podcast"},
|
|
|
|
|
187: {Sym: "indie_rock", Description: "Indie-Rock"},
|
|
|
|
|
188: {Sym: "g_funk", Description: "G-Funk"},
|
|
|
|
|
189: {Sym: "dubstep", Description: "Dubstep"},
|
|
|
|
|
190: {Sym: "garage_rock", Description: "Garage Rock"},
|
|
|
|
|
191: {Sym: "psybient", Description: "Psybient"},
|
2021-12-02 00:48:25 +03:00
|
|
|
|
})
|
2020-06-08 03:29:51 +03:00
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|