diff options
Diffstat (limited to 'lib/rbcodec/metadata/vtx.c')
-rw-r--r-- | lib/rbcodec/metadata/vtx.c | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/lib/rbcodec/metadata/vtx.c b/lib/rbcodec/metadata/vtx.c new file mode 100644 index 0000000000..eb06528b29 --- /dev/null +++ b/lib/rbcodec/metadata/vtx.c | |||
@@ -0,0 +1,150 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <string.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <ctype.h> | ||
5 | #include <inttypes.h> | ||
6 | #include "platform.h" | ||
7 | |||
8 | #include "metadata.h" | ||
9 | #include "metadata_common.h" | ||
10 | #include "metadata_parsers.h" | ||
11 | #include "rbunicode.h" | ||
12 | #include "string-extra.h" | ||
13 | |||
14 | typedef unsigned char uchar; | ||
15 | typedef unsigned short ushort; | ||
16 | typedef unsigned int uint; | ||
17 | typedef unsigned long ulong; | ||
18 | |||
19 | typedef enum { | ||
20 | VTX_CHIP_AY = 0, /* emulate AY */ | ||
21 | VTX_CHIP_YM /* emulate YM */ | ||
22 | } vtx_chiptype_t; | ||
23 | |||
24 | typedef enum { | ||
25 | VTX_LAYOUT_MONO = 0, | ||
26 | VTX_LAYOUT_ABC, | ||
27 | VTX_LAYOUT_ACB, | ||
28 | VTX_LAYOUT_BAC, | ||
29 | VTX_LAYOUT_BCA, | ||
30 | VTX_LAYOUT_CAB, | ||
31 | VTX_LAYOUT_CBA, | ||
32 | VTX_LAYOUT_CUSTOM | ||
33 | } vtx_layout_t; | ||
34 | |||
35 | typedef struct { | ||
36 | vtx_chiptype_t chiptype; /* Type of sound chip */ | ||
37 | vtx_layout_t layout; /* stereo layout */ | ||
38 | uint loop; /* song loop */ | ||
39 | uint chipfreq; /* AY chip freq (1773400 for ZX) */ | ||
40 | uint playerfreq; /* 50 Hz for ZX, 60 Hz for yamaha */ | ||
41 | uint year; /* year song composed */ | ||
42 | char *title; /* song title */ | ||
43 | char *author; /* song author */ | ||
44 | char *from; /* song from */ | ||
45 | char *tracker; /* tracker */ | ||
46 | char *comment; /* comment */ | ||
47 | uint regdata_size; /* size of unpacked data */ | ||
48 | uint frames; /* number of AY data frames */ | ||
49 | } vtx_info_t; | ||
50 | |||
51 | #define VTX_STRING_MAX 254 | ||
52 | |||
53 | static uint Reader_ReadByte(int fd) { | ||
54 | unsigned char c; | ||
55 | read(fd, &c, sizeof(c)); | ||
56 | return c; | ||
57 | } | ||
58 | |||
59 | static uint Reader_ReadWord(int fd) { | ||
60 | unsigned short s; | ||
61 | read(fd, &s, sizeof(s)); | ||
62 | return letoh16(s); | ||
63 | } | ||
64 | |||
65 | static uint Reader_ReadDWord(int fd) { | ||
66 | unsigned int i; | ||
67 | read(fd, &i, sizeof(i)); | ||
68 | return letoh32(i); | ||
69 | } | ||
70 | |||
71 | static char* Reader_ReadString(int fd, char *str) { | ||
72 | int i = 0; | ||
73 | char c = 1; | ||
74 | char *p = str; | ||
75 | |||
76 | if (str) | ||
77 | *str = 0; | ||
78 | |||
79 | while (i < VTX_STRING_MAX && c) { | ||
80 | read(fd, &c, sizeof(c)); | ||
81 | if (str) | ||
82 | *str++ = c; | ||
83 | i++; | ||
84 | } | ||
85 | |||
86 | if (str) | ||
87 | *str = 0; | ||
88 | |||
89 | return p; | ||
90 | } | ||
91 | |||
92 | /* vtx info */ | ||
93 | |||
94 | bool get_vtx_metadata(int fd, struct mp3entry* id3) | ||
95 | { | ||
96 | vtx_info_t info; | ||
97 | char *p = id3->id3v2buf; | ||
98 | char buf[VTX_STRING_MAX+1]; | ||
99 | |||
100 | if (lseek(fd, 0, SEEK_SET) < 0) | ||
101 | goto exit_bad; | ||
102 | |||
103 | if (filesize(fd) < 20) | ||
104 | goto exit_bad; | ||
105 | |||
106 | uint hdr = Reader_ReadWord(fd); | ||
107 | |||
108 | if ((hdr != 0x7961) && (hdr != 0x6d79)) | ||
109 | goto exit_bad; | ||
110 | |||
111 | info.layout = (vtx_layout_t)Reader_ReadByte(fd); | ||
112 | info.loop = Reader_ReadWord(fd); | ||
113 | info.chipfreq = Reader_ReadDWord(fd); | ||
114 | info.playerfreq = Reader_ReadByte(fd); | ||
115 | info.year = Reader_ReadWord(fd); | ||
116 | info.regdata_size = Reader_ReadDWord(fd); | ||
117 | info.frames = info.regdata_size / 14; | ||
118 | info.title = Reader_ReadString(fd, buf); | ||
119 | if (buf[0]) { | ||
120 | /* Title */ | ||
121 | id3->title = p; | ||
122 | p += strlcpy(p, info.title, VTX_STRING_MAX) + 1; | ||
123 | } | ||
124 | info.author = Reader_ReadString(fd, buf); | ||
125 | if (buf[0]) { | ||
126 | /* Artist */ | ||
127 | id3->artist = p; | ||
128 | p += strlcpy(p, info.author, VTX_STRING_MAX) + 1; | ||
129 | } | ||
130 | info.from = Reader_ReadString(fd, NULL); | ||
131 | info.tracker = Reader_ReadString(fd, NULL); | ||
132 | info.comment = Reader_ReadString(fd, buf); | ||
133 | if (buf[0]) { | ||
134 | /* Comment */ | ||
135 | id3->comment = p; | ||
136 | p += strlcpy(p, info.comment, VTX_STRING_MAX) + 1; | ||
137 | } | ||
138 | |||
139 | id3->vbr = false; | ||
140 | id3->bitrate = 706; | ||
141 | id3->frequency = 44100; // XXX allow this to be configured? | ||
142 | |||
143 | id3->filesize = filesize(fd); | ||
144 | id3->length = info.frames * 1000 / info.playerfreq; | ||
145 | |||
146 | return true; | ||
147 | |||
148 | exit_bad: | ||
149 | return false; | ||
150 | } | ||