diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2005-07-05 19:55:40 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2005-07-05 19:55:40 +0000 |
commit | 5c2c991d148de6aafae4836f4e40edb453734d94 (patch) | |
tree | 8bc792d3422894aad42643ddf13a025dc2084104 | |
parent | 1e5119b77bda5f67ad032a9587ead2d311b0767a (diff) | |
download | rockbox-5c2c991d148de6aafae4836f4e40edb453734d94.tar.gz rockbox-5c2c991d148de6aafae4836f4e40edb453734d94.zip |
Applied patch "[ 1232957 ] MP3 metadata fixes for software codec".
Thanks to Magnus Holmgren. Now metadata reading is better with
improved performance for mp3 files.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7030 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/codecs.c | 1 | ||||
-rw-r--r-- | apps/codecs.h | 1 | ||||
-rw-r--r-- | apps/codecs/mpa.c | 17 | ||||
-rw-r--r-- | apps/metadata.c | 5 | ||||
-rw-r--r-- | apps/playback.c | 3 | ||||
-rw-r--r-- | apps/playback.h | 3 | ||||
-rw-r--r-- | firmware/export/id3.h | 5 | ||||
-rw-r--r-- | firmware/id3.c | 5 | ||||
-rw-r--r-- | firmware/mp3data.c | 2 |
9 files changed, 19 insertions, 23 deletions
diff --git a/apps/codecs.c b/apps/codecs.c index 8b4f9b5f32..d3a9d9e9c1 100644 --- a/apps/codecs.c +++ b/apps/codecs.c | |||
@@ -74,7 +74,6 @@ struct codec_api ci = { | |||
74 | 0, /* filesize */ | 74 | 0, /* filesize */ |
75 | 0, /* curpos */ | 75 | 0, /* curpos */ |
76 | NULL, /* id3 */ | 76 | NULL, /* id3 */ |
77 | NULL, /* mp3data */ | ||
78 | NULL, /* taginfo_ready */ | 77 | NULL, /* taginfo_ready */ |
79 | false, /* stop_codec */ | 78 | false, /* stop_codec */ |
80 | false, /* reload_codec */ | 79 | false, /* reload_codec */ |
diff --git a/apps/codecs.h b/apps/codecs.h index 5878ca9185..ea5972968f 100644 --- a/apps/codecs.h +++ b/apps/codecs.h | |||
@@ -121,7 +121,6 @@ struct codec_api { | |||
121 | 121 | ||
122 | /* For gapless mp3 */ | 122 | /* For gapless mp3 */ |
123 | struct mp3entry *id3; /* TAG metadata pointer */ | 123 | struct mp3entry *id3; /* TAG metadata pointer */ |
124 | struct mp3info *mp3data; /* MP3 metadata pointer */ | ||
125 | bool *taginfo_ready; /* Is metadata read */ | 124 | bool *taginfo_ready; /* Is metadata read */ |
126 | 125 | ||
127 | /* Codec should periodically check if stop_codec is set to true. | 126 | /* Codec should periodically check if stop_codec is set to true. |
diff --git a/apps/codecs/mpa.c b/apps/codecs/mpa.c index df78b07247..5cf4eb8730 100644 --- a/apps/codecs/mpa.c +++ b/apps/codecs/mpa.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include "playback.h" | 24 | #include "playback.h" |
25 | #include "dsp.h" | 25 | #include "dsp.h" |
26 | #include "mp3data.h" | ||
27 | #include "lib/codeclib.h" | 26 | #include "lib/codeclib.h" |
28 | 27 | ||
29 | struct mad_stream Stream IDATA_ATTR; | 28 | struct mad_stream Stream IDATA_ATTR; |
@@ -61,7 +60,6 @@ extern char iramend[]; | |||
61 | enum codec_status codec_start(struct codec_api* api) | 60 | enum codec_status codec_start(struct codec_api* api) |
62 | { | 61 | { |
63 | struct codec_api *ci = api; | 62 | struct codec_api *ci = api; |
64 | struct mp3info *info; | ||
65 | int Status = 0; | 63 | int Status = 0; |
66 | size_t size; | 64 | size_t size; |
67 | int file_end; | 65 | int file_end; |
@@ -115,7 +113,6 @@ enum codec_status codec_start(struct codec_api* api) | |||
115 | for gapless playback */ | 113 | for gapless playback */ |
116 | next_track: | 114 | next_track: |
117 | 115 | ||
118 | info = ci->mp3data; | ||
119 | first_frame = false; | 116 | first_frame = false; |
120 | file_end = 0; | 117 | file_end = 0; |
121 | OutputPtr = OutputBuffer; | 118 | OutputPtr = OutputBuffer; |
@@ -128,24 +125,24 @@ enum codec_status codec_start(struct codec_api* api) | |||
128 | 125 | ||
129 | ci->request_buffer(&size, ci->id3->first_frame_offset); | 126 | ci->request_buffer(&size, ci->id3->first_frame_offset); |
130 | ci->advance_buffer(size); | 127 | ci->advance_buffer(size); |
131 | 128 | ||
132 | if (info->enc_delay >= 0 && info->enc_padding >= 0) { | 129 | if (ci->id3->lead_trim >= 0 && ci->id3->tail_trim >= 0) { |
133 | stop_skip = info->enc_padding - mpeg_latency[info->layer]; | 130 | stop_skip = ci->id3->tail_trim - mpeg_latency[ci->id3->layer]; |
134 | if (stop_skip < 0) stop_skip = 0; | 131 | if (stop_skip < 0) stop_skip = 0; |
135 | start_skip = info->enc_delay + mpeg_latency[info->layer]; | 132 | start_skip = ci->id3->lead_trim + mpeg_latency[ci->id3->layer]; |
136 | } else { | 133 | } else { |
137 | stop_skip = 0; | 134 | stop_skip = 0; |
138 | /* We want to skip this amount anyway */ | 135 | /* We want to skip this amount anyway */ |
139 | start_skip = mpeg_latency[info->layer]; | 136 | start_skip = mpeg_latency[ci->id3->layer]; |
140 | } | 137 | } |
141 | 138 | ||
142 | /* NOTE: currently this doesn't work, the below calculated samples_count | 139 | /* NOTE: currently this doesn't work, the below calculated samples_count |
143 | seems to be right, but sometimes libmad just can't supply us with | 140 | seems to be right, but sometimes libmad just can't supply us with |
144 | all the data we need... */ | 141 | all the data we need... */ |
145 | if (info->frame_count) { | 142 | if (ci->id3->frame_count) { |
146 | /* TODO: 1152 is the frame size in samples for MPEG1 layer 2 and layer 3, | 143 | /* TODO: 1152 is the frame size in samples for MPEG1 layer 2 and layer 3, |
147 | it's probably not correct at all for MPEG2 and layer 1 */ | 144 | it's probably not correct at all for MPEG2 and layer 1 */ |
148 | samplecount = info->frame_count*1152 - (start_skip + stop_skip); | 145 | samplecount = ci->id3->frame_count*1152 - (start_skip + stop_skip); |
149 | samplesdone = ci->id3->elapsed * frequency_divider / 10; | 146 | samplesdone = ci->id3->elapsed * frequency_divider / 10; |
150 | } else { | 147 | } else { |
151 | samplecount = ci->id3->length * frequency_divider / 10; | 148 | samplecount = ci->id3->length * frequency_divider / 10; |
diff --git a/apps/metadata.c b/apps/metadata.c index 6ba2331d26..0e770dde7a 100644 --- a/apps/metadata.c +++ b/apps/metadata.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include "metadata.h" | 24 | #include "metadata.h" |
25 | #include "mp3_playback.h" | 25 | #include "mp3_playback.h" |
26 | #include "mp3data.h" | ||
27 | #include "logf.h" | 26 | #include "logf.h" |
28 | #include "atoi.h" | 27 | #include "atoi.h" |
29 | 28 | ||
@@ -113,10 +112,6 @@ bool get_metadata(struct track_info* track, int fd, const char* trackname, | |||
113 | mp3info(&track->id3, trackname, v1first); | 112 | mp3info(&track->id3, trackname, v1first); |
114 | lseek(fd, 0, SEEK_SET); | 113 | lseek(fd, 0, SEEK_SET); |
115 | 114 | ||
116 | /* This is too slow to execute on some files. */ | ||
117 | get_mp3file_info(fd, &track->mp3data); | ||
118 | lseek(fd, 0, SEEK_SET); | ||
119 | |||
120 | /* | 115 | /* |
121 | logf("T:%s", track->id3.title); | 116 | logf("T:%s", track->id3.title); |
122 | logf("L:%d", track->id3.length); | 117 | logf("L:%d", track->id3.length); |
diff --git a/apps/playback.c b/apps/playback.c index 8186cf3191..11ef7d7a04 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include "audio.h" | 39 | #include "audio.h" |
40 | #include "logf.h" | 40 | #include "logf.h" |
41 | #include "mp3_playback.h" | 41 | #include "mp3_playback.h" |
42 | #include "mp3data.h" | ||
43 | #include "usb.h" | 42 | #include "usb.h" |
44 | #include "status.h" | 43 | #include "status.h" |
45 | #include "main_menu.h" | 44 | #include "main_menu.h" |
@@ -738,7 +737,6 @@ bool loadcodec(const char *trackname, bool start_play) | |||
738 | cur_ti = &tracks[track_widx]; | 737 | cur_ti = &tracks[track_widx]; |
739 | ci.filesize = cur_ti->filesize; | 738 | ci.filesize = cur_ti->filesize; |
740 | ci.id3 = (struct mp3entry *)&cur_ti->id3; | 739 | ci.id3 = (struct mp3entry *)&cur_ti->id3; |
741 | ci.mp3data = (struct mp3info *)&cur_ti->mp3data; | ||
742 | ci.taginfo_ready = (bool *)&cur_ti->taginfo_ready; | 740 | ci.taginfo_ready = (bool *)&cur_ti->taginfo_ready; |
743 | ci.curpos = 0; | 741 | ci.curpos = 0; |
744 | playing = true; | 742 | playing = true; |
@@ -1179,7 +1177,6 @@ void audio_update_trackinfo(void) | |||
1179 | cur_ti->id3.elapsed = 0; | 1177 | cur_ti->id3.elapsed = 0; |
1180 | cur_ti->id3.offset = 0; | 1178 | cur_ti->id3.offset = 0; |
1181 | ci.id3 = (struct mp3entry *)&cur_ti->id3; | 1179 | ci.id3 = (struct mp3entry *)&cur_ti->id3; |
1182 | ci.mp3data = (struct mp3info *)&cur_ti->mp3data; | ||
1183 | ci.curpos = 0; | 1180 | ci.curpos = 0; |
1184 | cur_ti->start_pos = 0; | 1181 | cur_ti->start_pos = 0; |
1185 | ci.taginfo_ready = (bool *)&cur_ti->taginfo_ready; | 1182 | ci.taginfo_ready = (bool *)&cur_ti->taginfo_ready; |
diff --git a/apps/playback.h b/apps/playback.h index 48d533f138..cb006f9e52 100644 --- a/apps/playback.h +++ b/apps/playback.h | |||
@@ -44,10 +44,9 @@ enum { | |||
44 | /* Not yet implemented. */ | 44 | /* Not yet implemented. */ |
45 | #define CODEC_SET_AUDIOBUF_WATERMARK 4 | 45 | #define CODEC_SET_AUDIOBUF_WATERMARK 4 |
46 | 46 | ||
47 | #define MAX_TRACK 10 | 47 | #define MAX_TRACK 32 |
48 | struct track_info { | 48 | struct track_info { |
49 | struct mp3entry id3; /* TAG metadata */ | 49 | struct mp3entry id3; /* TAG metadata */ |
50 | struct mp3info mp3data; /* MP3 metadata */ | ||
51 | char *codecbuf; /* Pointer to codec buffer */ | 50 | char *codecbuf; /* Pointer to codec buffer */ |
52 | long codecsize; /* Codec length in bytes */ | 51 | long codecsize; /* Codec length in bytes */ |
53 | 52 | ||
diff --git a/firmware/export/id3.h b/firmware/export/id3.h index 8f904e49e6..7970f529f1 100644 --- a/firmware/export/id3.h +++ b/firmware/export/id3.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #ifndef ID3_H | 19 | #ifndef ID3_H |
20 | #define ID3_H | 20 | #define ID3_H |
21 | 21 | ||
22 | #include <stdbool.h> | ||
22 | #include "config.h" | 23 | #include "config.h" |
23 | #include "file.h" | 24 | #include "file.h" |
24 | 25 | ||
@@ -78,12 +79,16 @@ struct mp3entry { | |||
78 | unsigned int length; /* song length */ | 79 | unsigned int length; /* song length */ |
79 | unsigned int elapsed; /* ms played */ | 80 | unsigned int elapsed; /* ms played */ |
80 | 81 | ||
82 | int lead_trim; /* Number of samples to skip at the beginning */ | ||
83 | int tail_trim; /* Number of samples to remove from the end */ | ||
84 | |||
81 | /* Added for Vorbis */ | 85 | /* Added for Vorbis */ |
82 | unsigned long samples; /* number of samples in track */ | 86 | unsigned long samples; /* number of samples in track */ |
83 | 87 | ||
84 | /* MP3 stream specific info */ | 88 | /* MP3 stream specific info */ |
85 | long bpf; /* bytes per frame */ | 89 | long bpf; /* bytes per frame */ |
86 | long tpf; /* time per frame */ | 90 | long tpf; /* time per frame */ |
91 | long frame_count; /* number of frames in the file (if VBR) */ | ||
87 | 92 | ||
88 | /* Xing VBR fields */ | 93 | /* Xing VBR fields */ |
89 | bool vbr; | 94 | bool vbr; |
diff --git a/firmware/id3.c b/firmware/id3.c index 6a13de4e29..4fe9fa0a40 100644 --- a/firmware/id3.c +++ b/firmware/id3.c | |||
@@ -832,9 +832,14 @@ static int getsonglength(int fd, struct mp3entry *entry) | |||
832 | 832 | ||
833 | entry->tpf = info.frame_time; | 833 | entry->tpf = info.frame_time; |
834 | entry->bpf = info.frame_size; | 834 | entry->bpf = info.frame_size; |
835 | entry->frame_count = info.frame_count; | ||
835 | 836 | ||
836 | entry->vbr = info.is_vbr; | 837 | entry->vbr = info.is_vbr; |
837 | entry->has_toc = info.has_toc; | 838 | entry->has_toc = info.has_toc; |
839 | |||
840 | entry->lead_trim = info.enc_delay; | ||
841 | entry->tail_trim = info.enc_padding; | ||
842 | |||
838 | memcpy(entry->toc, info.toc, sizeof(info.toc)); | 843 | memcpy(entry->toc, info.toc, sizeof(info.toc)); |
839 | 844 | ||
840 | entry->vbr_header_pos = info.vbr_header_pos; | 845 | entry->vbr_header_pos = info.vbr_header_pos; |
diff --git a/firmware/mp3data.c b/firmware/mp3data.c index e899125013..087bcf5030 100644 --- a/firmware/mp3data.c +++ b/firmware/mp3data.c | |||
@@ -266,7 +266,7 @@ static int fileread(int fd, unsigned char *c) | |||
266 | #if defined(IRIVER_H100) && !defined(SIMULATOR) | 266 | #if defined(IRIVER_H100) && !defined(SIMULATOR) |
267 | /* We don't want to eat all cpu power. Maybe better way to do this | 267 | /* We don't want to eat all cpu power. Maybe better way to do this |
268 | should be implemented. */ | 268 | should be implemented. */ |
269 | while (pcm_is_lowdata()) | 269 | if (pcm_is_lowdata()) |
270 | yield(); | 270 | yield(); |
271 | #endif | 271 | #endif |
272 | 272 | ||