summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-12-05 14:55:14 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-12-05 14:55:14 +0000
commit345f7c62ba7247b84990364a2e906cf805d6c406 (patch)
treeff65c1a8c683236d1c68229b6467641e5a540483
parentd29248d992b65e71976bd46b9c4697a89d1bec4d (diff)
downloadrockbox-345f7c62ba7247b84990364a2e906cf805d6c406.tar.gz
rockbox-345f7c62ba7247b84990364a2e906cf805d6c406.zip
Added ID3 tag 'year': %iy
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2949 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/wps-display.c9
-rw-r--r--firmware/id3.c137
-rw-r--r--firmware/id3.h1
3 files changed, 68 insertions, 79 deletions
diff --git a/apps/wps-display.c b/apps/wps-display.c
index ed6b1d10cc..521d2b5d77 100644
--- a/apps/wps-display.c
+++ b/apps/wps-display.c
@@ -251,6 +251,15 @@ static char* get_tag(struct mp3entry* id3,
251 251
252 case 'd': /* ID3 Album/Disc */ 252 case 'd': /* ID3 Album/Disc */
253 return id3->album; 253 return id3->album;
254
255 case 'y': /* year */
256 if (id3->year) {
257 snprintf(buf, buf_size, "%d", id3->year);
258 return buf;
259 }
260 else
261 return NULL;
262 break;
254 } 263 }
255 break; 264 break;
256 265
diff --git a/firmware/id3.c b/firmware/id3.c
index ed2724fe9f..c0e6c564d0 100644
--- a/firmware/id3.c
+++ b/firmware/id3.c
@@ -146,30 +146,6 @@ static int unicode_munge(char** string, int *len) {
146} 146}
147 147
148/* 148/*
149 * Removes trailing spaces from a string.
150 *
151 * Arguments: buffer - the string to process
152 *
153 * Returns: void
154 */
155static void
156stripspaces(char *buffer)
157{
158 int i = 0;
159 while(*(buffer + i) != '\0')
160 i++;
161
162 for(;i >= 0; i--) {
163 if(*(buffer + i) == ' ')
164 *(buffer + i) = '\0';
165 else if(*(buffer + i) == '\0')
166 continue;
167 else
168 break;
169 }
170}
171
172/*
173 * Sets the title of an MP3 entry based on its ID3v1 tag. 149 * Sets the title of an MP3 entry based on its ID3v1 tag.
174 * 150 *
175 * Arguments: file - the MP3 file to scen for a ID3v1 tag 151 * Arguments: file - the MP3 file to scen for a ID3v1 tag
@@ -179,39 +155,55 @@ stripspaces(char *buffer)
179 */ 155 */
180static bool setid3v1title(int fd, struct mp3entry *entry) 156static bool setid3v1title(int fd, struct mp3entry *entry)
181{ 157{
182 unsigned char buffer[31]; 158 unsigned char buffer[128];
183 int offsets[4] = {-95,-65,-125,-31}; 159 static int offsets[] = {3, 33, 63, 93, 125};
184 int i; 160 int i, j;
161
162 if (-1 == lseek(fd, -128, SEEK_END))
163 return false;
185 164
186 for (i=0;i<4;i++) { 165 if (read(fd, buffer, sizeof buffer) != sizeof buffer)
187 if (-1 == lseek(fd, offsets[i], SEEK_END)) 166 return false;
188 return false; 167
168 if (strncmp(buffer, "TAG", 3))
169 return false;
189 170
190 buffer[30]=0; 171 for (i=0;i<5;i++) {
191 read(fd, buffer, 30); 172 char* ptr = buffer + offsets[i];
192 stripspaces(buffer);
193 173
194 if (buffer[0] || i == 3) { 174 if (i<3) {
195 switch(i) { 175 /* kill trailing space in strings */
196 case 0: 176 for (j=29; j && ptr[j]==' '; j--)
197 strcpy(entry->id3v1buf[0], buffer); 177 ptr[j] = 0;
198 entry->artist = entry->id3v1buf[0]; 178 }
199 break; 179
200 case 1: 180 switch(i) {
201 strcpy(entry->id3v1buf[1], buffer); 181 case 0:
202 entry->album = entry->id3v1buf[1]; 182 strcpy(entry->id3v1buf[2], ptr);
203 break; 183 entry->title = entry->id3v1buf[2];
204 case 2: 184 break;
205 strcpy(entry->id3v1buf[2], buffer); 185
206 entry->title = entry->id3v1buf[2]; 186 case 1:
207 break; 187 strcpy(entry->id3v1buf[0], ptr);
208 case 3: 188 entry->artist = entry->id3v1buf[0];
209 /* id3v1.1 uses last two bytes of comment field for track 189 break;
210 number: first must be 0 and second is track num */ 190
211 if (buffer[28] == 0) 191 case 2:
212 entry->tracknum = buffer[29]; 192 strcpy(entry->id3v1buf[1], ptr);
213 break; 193 entry->album = entry->id3v1buf[1];
214 } 194 break;
195
196 case 3:
197 ptr[4] = 0;
198 entry->year = atoi(ptr);
199 break;
200
201 case 4:
202 /* id3v1.1 uses last two bytes of comment field for track
203 number: first must be 0 and second is track num */
204 if (*ptr == 0)
205 entry->tracknum = ptr[1];
206 break;
215 } 207 }
216 } 208 }
217 209
@@ -300,6 +292,8 @@ static void setid3v2title(int fd, struct mp3entry *entry)
300 if(framelen >= buffersize - bufferpos) 292 if(framelen >= buffersize - bufferpos)
301 framelen = buffersize - bufferpos - 1; 293 framelen = buffersize - bufferpos - 1;
302 294
295 DEBUGF("id3v2 frame: %.4s\n", header);
296
303 /* Check for certain frame headers */ 297 /* Check for certain frame headers */
304 if(!strncmp(header, "TPE1", strlen("TPE1")) || 298 if(!strncmp(header, "TPE1", strlen("TPE1")) ||
305 !strncmp(header, "TP1", strlen("TP1"))) { 299 !strncmp(header, "TP1", strlen("TP1"))) {
@@ -336,6 +330,15 @@ static void setid3v2title(int fd, struct mp3entry *entry)
336 bufferpos += bytesread + 1; 330 bufferpos += bytesread + 1;
337 size -= bytesread; 331 size -= bytesread;
338 } 332 }
333 else if(!strncmp(header, "TYER", 4) ||
334 !strncmp(header, "TYR", 3)) {
335 char* ptr = buffer + bufferpos;
336 bytesread = read(fd, ptr, framelen);
337 unicode_munge(&ptr, &bytesread);
338 entry->year = atoi(ptr);
339 bufferpos += bytesread + 1;
340 size -= bytesread;
341 }
339 else { 342 else {
340 /* Unknown frame, skip it using the total size in case 343 /* Unknown frame, skip it using the total size in case
341 it was truncated */ 344 it was truncated */
@@ -384,29 +387,6 @@ static int getfilesize(int fd)
384 return size; 387 return size;
385} 388}
386 389
387/*
388 * Calculates the size of the ID3v1 tag.
389 *
390 * Arguments: file - the file to search for a tag.
391 *
392 * Returns: the size of the tag or 0 if none was found
393 */
394static int getid3v1len(int fd)
395{
396 char buf[3];
397 int offset;
398
399 /* Check if we find "TAG" 128 bytes from EOF */
400 if((lseek(fd, -128, SEEK_END) == -1) ||
401 (read(fd, buf, 3) != 3) ||
402 (strncmp(buf, "TAG", 3) != 0))
403 offset = 0;
404 else
405 offset = 128;
406
407 return offset;
408}
409
410/* check if 'head' is a valid mp3 frame header */ 390/* check if 'head' is a valid mp3 frame header */
411static bool mp3frameheader(unsigned long head) 391static bool mp3frameheader(unsigned long head)
412{ 392{
@@ -739,8 +719,7 @@ bool mp3info(struct mp3entry *entry, char *filename)
739 719
740 /* only seek to end of file if no id3v2 tags were found */ 720 /* only seek to end of file if no id3v2 tags were found */
741 if (!entry->id3v2len) { 721 if (!entry->id3v2len) {
742 entry->id3v1len = getid3v1len(fd); 722 if(!entry->title)
743 if(entry->id3v1len && !entry->title)
744 setid3v1title(fd, entry); 723 setid3v1title(fd, entry);
745 } 724 }
746 725
diff --git a/firmware/id3.h b/firmware/id3.h
index 88f50ba9b1..ae88bbf16c 100644
--- a/firmware/id3.h
+++ b/firmware/id3.h
@@ -29,6 +29,7 @@ struct mp3entry {
29 int tracknum; 29 int tracknum;
30 int version; 30 int version;
31 int layer; 31 int layer;
32 int year;
32 unsigned int bitrate; 33 unsigned int bitrate;
33 unsigned int frequency; 34 unsigned int frequency;
34 unsigned int id3v2len; 35 unsigned int id3v2len;