diff options
author | Dave Chapman <dave@dchapman.com> | 2007-06-06 17:46:49 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2007-06-06 17:46:49 +0000 |
commit | c995ae8026b4e22159695a7b8c856bc0d8d5328b (patch) | |
tree | 9fec68ba229fbcd9a115de4d7a87a4421e621797 | |
parent | 6c31a9a9d3611edb811964a80e15449a54634c83 (diff) | |
download | rockbox-c995ae8026b4e22159695a7b8c856bc0d8d5328b.tar.gz rockbox-c995ae8026b4e22159695a7b8c856bc0d8d5328b.zip |
Make v3.97 APE files work in Rockbox
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13571 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/codecs/demac/libdemac/parser.c | 90 | ||||
-rw-r--r-- | apps/metadata.c | 45 |
2 files changed, 95 insertions, 40 deletions
diff --git a/apps/codecs/demac/libdemac/parser.c b/apps/codecs/demac/libdemac/parser.c index bcb542dbb6..4e907308b6 100644 --- a/apps/codecs/demac/libdemac/parser.c +++ b/apps/codecs/demac/libdemac/parser.c | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | libdemac - A Monkey's Audio decoder | 3 | libdemac - A Monkey's Audio decoder |
4 | 4 | ||
5 | $Id:$ | 5 | $Id$ |
6 | 6 | ||
7 | Copyright (C) Dave Chapman 2007 | 7 | Copyright (C) Dave Chapman 2007 |
8 | 8 | ||
@@ -70,39 +70,71 @@ int ape_parseheaderbuf(unsigned char* buf, struct ape_ctx_t* ape_ctx) | |||
70 | 70 | ||
71 | if (ape_ctx->fileversion >= 3980) | 71 | if (ape_ctx->fileversion >= 3980) |
72 | { | 72 | { |
73 | ape_ctx->padding1 = get_int16(buf + 6); | 73 | ape_ctx->padding1 = get_int16(buf + 6); |
74 | ape_ctx->descriptorlength = get_uint32(buf + 8); | 74 | ape_ctx->descriptorlength = get_uint32(buf + 8); |
75 | ape_ctx->headerlength = get_uint32(buf + 12); | 75 | ape_ctx->headerlength = get_uint32(buf + 12); |
76 | ape_ctx->seektablelength = get_uint32(buf + 16); | 76 | ape_ctx->seektablelength = get_uint32(buf + 16); |
77 | ape_ctx->wavheaderlength = get_uint32(buf + 20); | 77 | ape_ctx->wavheaderlength = get_uint32(buf + 20); |
78 | ape_ctx->audiodatalength = get_uint32(buf + 24); | 78 | ape_ctx->audiodatalength = get_uint32(buf + 24); |
79 | ape_ctx->audiodatalength_high = get_uint32(buf + 28); | 79 | ape_ctx->audiodatalength_high = get_uint32(buf + 28); |
80 | ape_ctx->wavtaillength = get_uint32(buf + 32); | 80 | ape_ctx->wavtaillength = get_uint32(buf + 32); |
81 | memcpy(ape_ctx->md5, buf + 36, 16); | 81 | memcpy(ape_ctx->md5, buf + 36, 16); |
82 | 82 | ||
83 | header = buf + ape_ctx->descriptorlength; | 83 | header = buf + ape_ctx->descriptorlength; |
84 | |||
85 | /* Read header data */ | ||
86 | ape_ctx->compressiontype = get_uint16(header + 0); | ||
87 | ape_ctx->formatflags = get_uint16(header + 2); | ||
88 | ape_ctx->blocksperframe = get_uint32(header + 4); | ||
89 | ape_ctx->finalframeblocks = get_uint32(header + 8); | ||
90 | ape_ctx->totalframes = get_uint32(header + 12); | ||
91 | ape_ctx->bps = get_uint16(header + 16); | ||
92 | ape_ctx->channels = get_uint16(header + 18); | ||
93 | ape_ctx->samplerate = get_uint32(header + 20); | ||
94 | 84 | ||
95 | ape_ctx->firstframe = ape_ctx->junklength + ape_ctx->descriptorlength + | 85 | /* Read header data */ |
96 | ape_ctx->headerlength + ape_ctx->seektablelength + | 86 | ape_ctx->compressiontype = get_uint16(header + 0); |
97 | ape_ctx->wavheaderlength; | 87 | ape_ctx->formatflags = get_uint16(header + 2); |
88 | ape_ctx->blocksperframe = get_uint32(header + 4); | ||
89 | ape_ctx->finalframeblocks = get_uint32(header + 8); | ||
90 | ape_ctx->totalframes = get_uint32(header + 12); | ||
91 | ape_ctx->bps = get_uint16(header + 16); | ||
92 | ape_ctx->channels = get_uint16(header + 18); | ||
93 | ape_ctx->samplerate = get_uint32(header + 20); | ||
94 | |||
95 | ape_ctx->firstframe = ape_ctx->junklength + ape_ctx->descriptorlength + | ||
96 | ape_ctx->headerlength + ape_ctx->seektablelength + | ||
97 | ape_ctx->wavheaderlength; | ||
98 | } else { | 98 | } else { |
99 | ape_ctx->headerlength = 32; | ||
99 | ape_ctx->compressiontype = get_uint16(buf + 6); | 100 | ape_ctx->compressiontype = get_uint16(buf + 6); |
100 | ape_ctx->formatflags = get_uint16(buf + 8); | 101 | ape_ctx->formatflags = get_uint16(buf + 8); |
101 | ape_ctx->channels = get_uint16(buf + 10); | 102 | ape_ctx->channels = get_uint16(buf + 10); |
102 | ape_ctx->samplerate = get_uint32(buf + 14); | 103 | ape_ctx->samplerate = get_uint32(buf + 12); |
103 | ape_ctx->wavheaderlength = get_uint32(buf + 18); | 104 | ape_ctx->wavheaderlength = get_uint32(buf + 16); |
104 | ape_ctx->totalframes = get_uint32(buf + 26); | 105 | ape_ctx->totalframes = get_uint32(buf + 24); |
105 | ape_ctx->finalframeblocks = get_uint32(buf + 30); | 106 | ape_ctx->finalframeblocks = get_uint32(buf + 28); |
107 | |||
108 | if (ape_ctx->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL) | ||
109 | { | ||
110 | ape_ctx->headerlength += 4; | ||
111 | } | ||
112 | |||
113 | if (ape_ctx->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS) | ||
114 | { | ||
115 | ape_ctx->seektablelength = get_uint32(buf + ape_ctx->headerlength); | ||
116 | ape_ctx->seektablelength *= sizeof(int32_t); | ||
117 | ape_ctx->headerlength += 4; | ||
118 | } else { | ||
119 | ape_ctx->seektablelength = ape_ctx->totalframes * sizeof(int32_t); | ||
120 | } | ||
121 | |||
122 | if (ape_ctx->formatflags & MAC_FORMAT_FLAG_8_BIT) | ||
123 | ape_ctx->bps = 8; | ||
124 | else if (ape_ctx->formatflags & MAC_FORMAT_FLAG_24_BIT) | ||
125 | ape_ctx->bps = 24; | ||
126 | else | ||
127 | ape_ctx->bps = 16; | ||
128 | |||
129 | if (ape_ctx->fileversion >= 3950) | ||
130 | ape_ctx->blocksperframe = 73728 * 4; | ||
131 | else if ((ape_ctx->fileversion >= 3900) || (ape_ctx->fileversion >= 3800 && ape_ctx->compressiontype >= 4000)) | ||
132 | ape_ctx->blocksperframe = 73728; | ||
133 | else | ||
134 | ape_ctx->blocksperframe = 9216; | ||
135 | |||
136 | ape_ctx->firstframe = ape_ctx->junklength + ape_ctx->headerlength + | ||
137 | ape_ctx->seektablelength + ape_ctx->wavheaderlength; | ||
106 | } | 138 | } |
107 | 139 | ||
108 | ape_ctx->totalsamples = ape_ctx->finalframeblocks; | 140 | ape_ctx->totalsamples = ape_ctx->finalframeblocks; |
diff --git a/apps/metadata.c b/apps/metadata.c index 60191b1eb8..594226b649 100644 --- a/apps/metadata.c +++ b/apps/metadata.c | |||
@@ -183,6 +183,14 @@ static unsigned long get_long_le(void* buf) | |||
183 | return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); | 183 | return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); |
184 | } | 184 | } |
185 | 185 | ||
186 | /* Read an unaligned 16-bit little endian short from buffer. */ | ||
187 | static unsigned short get_short_le(void* buf) | ||
188 | { | ||
189 | unsigned char* p = (unsigned char*) buf; | ||
190 | |||
191 | return p[0] | (p[1] << 8); | ||
192 | } | ||
193 | |||
186 | /* Read an unaligned 32-bit big endian long from buffer. */ | 194 | /* Read an unaligned 32-bit big endian long from buffer. */ |
187 | static unsigned long get_long_be(void* buf) | 195 | static unsigned long get_long_be(void* buf) |
188 | { | 196 | { |
@@ -991,6 +999,7 @@ static bool get_monkeys_metadata(int fd, struct mp3entry* id3) | |||
991 | uint32_t descriptorlength; | 999 | uint32_t descriptorlength; |
992 | uint32_t totalsamples; | 1000 | uint32_t totalsamples; |
993 | uint32_t blocksperframe, finalframeblocks, totalframes; | 1001 | uint32_t blocksperframe, finalframeblocks, totalframes; |
1002 | int fileversion; | ||
994 | 1003 | ||
995 | lseek(fd, 0, SEEK_SET); | 1004 | lseek(fd, 0, SEEK_SET); |
996 | 1005 | ||
@@ -1006,22 +1015,36 @@ static bool get_monkeys_metadata(int fd, struct mp3entry* id3) | |||
1006 | 1015 | ||
1007 | read(fd, buf + 4, MAX_PATH - 4); | 1016 | read(fd, buf + 4, MAX_PATH - 4); |
1008 | 1017 | ||
1009 | descriptorlength = buf[8] | (buf[9] << 8) | | 1018 | fileversion = get_short_le(buf+4); |
1010 | (buf[10] << 16) | (buf[11] << 24); | 1019 | if (fileversion < 3970) |
1020 | { | ||
1021 | /* Not supported */ | ||
1022 | return false; | ||
1023 | } | ||
1011 | 1024 | ||
1012 | header = buf + descriptorlength; | 1025 | if (fileversion >= 3980) |
1026 | { | ||
1027 | descriptorlength = get_long_le(buf+8); | ||
1028 | |||
1029 | header = buf + descriptorlength; | ||
1013 | 1030 | ||
1014 | blocksperframe = header[4] | (header[5] << 8) | | 1031 | blocksperframe = get_long_le(header+4); |
1015 | (header[6] << 16) | (header[7] << 24); | 1032 | finalframeblocks = get_long_le(header+8); |
1016 | finalframeblocks = header[8] | (header[9] << 8) | | 1033 | totalframes = get_long_le(header+12); |
1017 | (header[10] << 16) | (header[11] << 24); | 1034 | id3->frequency = get_long_le(header+20); |
1018 | totalframes = header[12] | (header[13] << 8) | | 1035 | } |
1019 | (header[14] << 16) | (header[15] << 24); | 1036 | else |
1037 | { | ||
1038 | /* v3.95 and later files all have a fixed framesize */ | ||
1039 | blocksperframe = 73728 * 4; | ||
1040 | |||
1041 | finalframeblocks = get_long_le(buf+30); | ||
1042 | totalframes = get_long_le(buf+26); | ||
1043 | id3->frequency = get_long_le(buf+14); | ||
1044 | } | ||
1020 | 1045 | ||
1021 | id3->vbr = true; /* All FLAC files are VBR */ | 1046 | id3->vbr = true; /* All FLAC files are VBR */ |
1022 | id3->filesize = filesize(fd); | 1047 | id3->filesize = filesize(fd); |
1023 | id3->frequency = header[20] | (header[21] << 8) | | ||
1024 | (header[22] << 16) | (header[23] << 24); | ||
1025 | 1048 | ||
1026 | totalsamples = finalframeblocks; | 1049 | totalsamples = finalframeblocks; |
1027 | if (totalframes > 1) | 1050 | if (totalframes > 1) |