diff options
-rw-r--r-- | apps/metadata/mod.c | 62 |
1 files changed, 52 insertions, 10 deletions
diff --git a/apps/metadata/mod.c b/apps/metadata/mod.c index dbedc6e62f..9595729c0b 100644 --- a/apps/metadata/mod.c +++ b/apps/metadata/mod.c | |||
@@ -19,40 +19,82 @@ | |||
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #include <stdio.h> | 21 | #include <stdio.h> |
22 | #include <string.h> | ||
23 | #include <stdlib.h> | 22 | #include <stdlib.h> |
24 | #include <ctype.h> | 23 | #include <ctype.h> |
25 | #include <inttypes.h> | 24 | #include <inttypes.h> |
26 | 25 | ||
27 | #include "system.h" | 26 | #include "system.h" |
28 | #include "metadata.h" | 27 | #include "metadata.h" |
28 | #include <string-extra.h> | ||
29 | #include "metadata_common.h" | 29 | #include "metadata_common.h" |
30 | #include "metadata_parsers.h" | 30 | #include "metadata_parsers.h" |
31 | #include "rbunicode.h" | 31 | #include "rbunicode.h" |
32 | 32 | ||
33 | #define MODULEHEADERSIZE 0x438 | ||
34 | |||
33 | bool get_mod_metadata(int fd, struct mp3entry* id3) | 35 | bool get_mod_metadata(int fd, struct mp3entry* id3) |
34 | { | 36 | { |
35 | /* Use the trackname part of the id3 structure as a temporary buffer */ | 37 | /* Use the trackname part of the id3 structure as a temporary buffer */ |
36 | unsigned char buf[1084]; | 38 | unsigned char buf[MODULEHEADERSIZE]; |
37 | int read_bytes; | 39 | unsigned char id[4]; |
40 | bool is_mod_file = false; | ||
38 | char *p; | 41 | char *p; |
39 | |||
40 | 42 | ||
41 | if ((lseek(fd, 0, SEEK_SET) < 0) | 43 | if ((lseek(fd, 0, SEEK_SET) < 0) |
42 | || ((read_bytes = read(fd, buf, sizeof(buf))) < 1084)) | 44 | || (read(fd, buf, sizeof(buf)) < MODULEHEADERSIZE)) |
43 | { | 45 | { |
44 | return false; | 46 | return false; |
45 | } | 47 | } |
46 | 48 | ||
47 | /* We don't do file format checking here | 49 | if (read(fd, id, sizeof(id)) < (ssize_t)sizeof(id)) |
48 | * There can be .mod files without any signatures out there */ | 50 | return false; |
51 | |||
52 | /* Mod type checking based on MikMod */ | ||
53 | /* Protracker and variants */ | ||
54 | if ((!memcmp(id, "M.K.", 4)) || (!memcmp(id, "M!K!", 4))) { | ||
55 | is_mod_file = true; | ||
56 | } | ||
57 | |||
58 | /* Star Tracker */ | ||
59 | if (((!memcmp(id, "FLT", 3)) || (!memcmp(id, "EXO", 3))) && | ||
60 | (isdigit(id[3]))) { | ||
61 | char numchn = id[3] - '0'; | ||
62 | if (numchn == 4 || numchn == 8) | ||
63 | is_mod_file = true; | ||
64 | } | ||
65 | |||
66 | /* Oktalyzer (Amiga) */ | ||
67 | if (!memcmp(id, "OKTA", 4)) { | ||
68 | is_mod_file = true; | ||
69 | } | ||
70 | |||
71 | /* Oktalyser (Atari) */ | ||
72 | if (!memcmp(id, "CD81", 4)) { | ||
73 | is_mod_file = true; | ||
74 | } | ||
75 | |||
76 | /* Fasttracker */ | ||
77 | if ((!memcmp(id + 1, "CHN", 3)) && (isdigit(id[0]))) { | ||
78 | is_mod_file = true; | ||
79 | } | ||
80 | /* Fasttracker or Taketracker */ | ||
81 | if (((!memcmp(id + 2, "CH", 2)) || (!memcmp(id + 2, "CN", 2))) | ||
82 | && (isdigit(id[0])) && (isdigit(id[1]))) { | ||
83 | is_mod_file = true; | ||
84 | } | ||
85 | |||
86 | /* Don't try to play if we can't find a known mod type | ||
87 | * (there are mod files which have nothing to do with music) */ | ||
88 | if (!is_mod_file) | ||
89 | return false; | ||
49 | 90 | ||
50 | p = id3->id3v2buf; | 91 | p = id3->id3v2buf; |
51 | 92 | ||
52 | /* Copy Title */ | 93 | /* Copy Title */ |
53 | strcpy(p, &buf[0x00]); | 94 | if (strlcpy(p, buf, sizeof(id3->id3v2buf)) >= sizeof(id3->id3v2buf)) |
95 | return false; | ||
96 | |||
54 | id3->title = p; | 97 | id3->title = p; |
55 | p += strlen(p)+1; | ||
56 | 98 | ||
57 | id3->bitrate = filesize(fd)/1024; /* size in kb */ | 99 | id3->bitrate = filesize(fd)/1024; /* size in kb */ |
58 | id3->frequency = 44100; | 100 | id3->frequency = 44100; |