diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2013-03-06 19:36:24 -0500 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2013-03-06 19:47:05 -0500 |
commit | c73894213d7f1c53eac7ea3d08ce9dbe0187aa33 (patch) | |
tree | bbc1fc73c1fc2a3465901d25b00a44505d9e8831 | |
parent | 2f9e3cae2c567185a501f4e2a301665452a83350 (diff) | |
download | rockbox-c73894213d7f1c53eac7ea3d08ce9dbe0187aa33.tar.gz rockbox-c73894213d7f1c53eac7ea3d08ce9dbe0187aa33.zip |
VGM Codec: Improve time and fade behavior. Tweak minor misc.
Prevents cutoff of tracks, especially short ones:
* Extend looped tracks by fade length to fade at start of loop repeat.
* No fade occurs for non-repeating track only having an intro.
* Uses id3.tail_trim field to store fade duration.
Use libGME built-in elapsed time reporting instead of custom calculation:
* libGME already reports in milliseconds.
* Don't advance time counter when Repeat == One. It just runs the progress
over the length limit.
Fix a comment about sample rate and set the reported bitrate to be
accurate for 44.1 kHz stereo.
Change-Id: I3ede22bda0f9a941a3fef751f4d678eb0027344c
-rw-r--r-- | lib/rbcodec/codecs/vgm.c | 48 | ||||
-rw-r--r-- | lib/rbcodec/metadata/vgm.c | 12 |
2 files changed, 40 insertions, 20 deletions
diff --git a/lib/rbcodec/codecs/vgm.c b/lib/rbcodec/codecs/vgm.c index 416f772f1d..9f2f1b9c5e 100644 --- a/lib/rbcodec/codecs/vgm.c +++ b/lib/rbcodec/codecs/vgm.c | |||
@@ -23,6 +23,31 @@ static char *songbuf; /* destination for uncompressed song */ | |||
23 | static uint32_t songbuflen=0; /* size of the song buffer */ | 23 | static uint32_t songbuflen=0; /* size of the song buffer */ |
24 | static uint32_t songlen=0; /* used size of the song buffer */ | 24 | static uint32_t songlen=0; /* used size of the song buffer */ |
25 | 25 | ||
26 | static void codec_vgz_update_length(void) | ||
27 | { | ||
28 | ci->id3->length = Track_get_length( &vgm_emu ); | ||
29 | ci->id3->tail_trim = 4 * 1000; | ||
30 | |||
31 | if (vgm_emu.info.loop_length <= 0) | ||
32 | ci->id3->tail_trim = 0; | ||
33 | |||
34 | ci->id3->length += ci->id3->tail_trim; | ||
35 | } | ||
36 | |||
37 | static void codec_update_fade(void) | ||
38 | { | ||
39 | /* for REPEAT_ONE we disable track limits */ | ||
40 | Track_set_fade(&vgm_emu, | ||
41 | ci->loop_track() ? indefinite_count : | ||
42 | ci->id3->length - ci->id3->tail_trim, | ||
43 | ci->id3->tail_trim); | ||
44 | } | ||
45 | |||
46 | static void codec_update_elapsed(void) | ||
47 | { | ||
48 | ci->set_elapsed(ci->loop_track() ? 0 : Track_tell(&vgm_emu)); | ||
49 | } | ||
50 | |||
26 | /****************** rockbox interface ******************/ | 51 | /****************** rockbox interface ******************/ |
27 | 52 | ||
28 | /* this is the codec entry point */ | 53 | /* this is the codec entry point */ |
@@ -32,7 +57,7 @@ enum codec_status codec_main(enum codec_entry_call_reason reason) | |||
32 | /* we only render 16 bits */ | 57 | /* we only render 16 bits */ |
33 | ci->configure(DSP_SET_SAMPLE_DEPTH, 16); | 58 | ci->configure(DSP_SET_SAMPLE_DEPTH, 16); |
34 | 59 | ||
35 | /* 32 Khz, Interleaved stereo */ | 60 | /* 44 Khz, Interleaved stereo */ |
36 | ci->configure(DSP_SET_FREQUENCY, 44100); | 61 | ci->configure(DSP_SET_FREQUENCY, 44100); |
37 | ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED); | 62 | ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED); |
38 | 63 | ||
@@ -51,8 +76,6 @@ enum codec_status codec_run(void) | |||
51 | size_t n; | 76 | size_t n; |
52 | intptr_t param; | 77 | intptr_t param; |
53 | 78 | ||
54 | uint32_t elapsed_time = 0; | ||
55 | |||
56 | DEBUGF("VGM: next_track\n"); | 79 | DEBUGF("VGM: next_track\n"); |
57 | if (codec_init()) { | 80 | if (codec_init()) { |
58 | return CODEC_ERROR; | 81 | return CODEC_ERROR; |
@@ -95,7 +118,7 @@ enum codec_status codec_run(void) | |||
95 | 118 | ||
96 | /* Since metadata parser doesn't support VGZ | 119 | /* Since metadata parser doesn't support VGZ |
97 | will set song length here */ | 120 | will set song length here */ |
98 | ci->id3->length = Track_get_length( &vgm_emu ); | 121 | codec_vgz_update_length(); |
99 | } | 122 | } |
100 | else if ((err = Vgm_load_mem(&vgm_emu, buf, n, false))) { | 123 | else if ((err = Vgm_load_mem(&vgm_emu, buf, n, false))) { |
101 | DEBUGF("VGM: Vgm_load failed_mem (%s)\n", err); | 124 | DEBUGF("VGM: Vgm_load failed_mem (%s)\n", err); |
@@ -104,12 +127,8 @@ enum codec_status codec_run(void) | |||
104 | 127 | ||
105 | Vgm_start_track(&vgm_emu); | 128 | Vgm_start_track(&vgm_emu); |
106 | 129 | ||
107 | /* for REPEAT_ONE we disable track limits */ | ||
108 | if (!ci->loop_track()) { | ||
109 | Track_set_fade(&vgm_emu, ci->id3->length - 4000, 4000); | ||
110 | } | ||
111 | |||
112 | ci->set_elapsed(0); | 130 | ci->set_elapsed(0); |
131 | codec_update_fade(); | ||
113 | 132 | ||
114 | /* The main decoder loop */ | 133 | /* The main decoder loop */ |
115 | while (1) { | 134 | while (1) { |
@@ -119,23 +138,20 @@ enum codec_status codec_run(void) | |||
119 | break; | 138 | break; |
120 | 139 | ||
121 | if (action == CODEC_ACTION_SEEK_TIME) { | 140 | if (action == CODEC_ACTION_SEEK_TIME) { |
122 | ci->set_elapsed(param); | ||
123 | elapsed_time = param; | ||
124 | Track_seek(&vgm_emu, param); | 141 | Track_seek(&vgm_emu, param); |
142 | codec_update_elapsed(); | ||
125 | ci->seek_complete(); | 143 | ci->seek_complete(); |
126 | 144 | ||
127 | /* Set fade again in case we seek to start of song */ | 145 | /* Set fade again in case we seek to start of song */ |
128 | Track_set_fade(&vgm_emu, ci->id3->length - 4000, 4000); | 146 | codec_update_fade(); |
129 | } | 147 | } |
130 | 148 | ||
131 | /* Generate audio buffer */ | 149 | /* Generate audio buffer */ |
132 | err = Vgm_play(&vgm_emu, CHUNK_SIZE, samples); | 150 | err = Vgm_play(&vgm_emu, CHUNK_SIZE, samples); |
133 | if (err || Track_ended(&vgm_emu)) break; | 151 | if (err || Track_ended(&vgm_emu)) break; |
134 | 152 | ||
135 | ci->pcmbuf_insert(samples, NULL, CHUNK_SIZE >> 1); | 153 | ci->pcmbuf_insert(samples, NULL, CHUNK_SIZE / 2); |
136 | 154 | codec_update_elapsed(); | |
137 | elapsed_time += (CHUNK_SIZE / 2) * 10 / 441; | ||
138 | ci->set_elapsed(elapsed_time); | ||
139 | } | 155 | } |
140 | 156 | ||
141 | return CODEC_OK; | 157 | return CODEC_OK; |
diff --git a/lib/rbcodec/metadata/vgm.c b/lib/rbcodec/metadata/vgm.c index 7d3f45e204..03afb15a92 100644 --- a/lib/rbcodec/metadata/vgm.c +++ b/lib/rbcodec/metadata/vgm.c | |||
@@ -113,6 +113,8 @@ static long check_gd3_header( byte* h, long remain ) | |||
113 | static void get_vgm_length( struct header_t* h, struct mp3entry* id3 ) | 113 | static void get_vgm_length( struct header_t* h, struct mp3entry* id3 ) |
114 | { | 114 | { |
115 | long length = get_long_le( h->track_duration ) * 10 / 441; | 115 | long length = get_long_le( h->track_duration ) * 10 / 441; |
116 | id3->tail_trim = 4 * 1000; /* assume fade */ | ||
117 | |||
116 | if ( length > 0 ) | 118 | if ( length > 0 ) |
117 | { | 119 | { |
118 | long loop_length = 0, intro_length = 0; | 120 | long loop_length = 0, intro_length = 0; |
@@ -126,13 +128,15 @@ static void get_vgm_length( struct header_t* h, struct mp3entry* id3 ) | |||
126 | { | 128 | { |
127 | intro_length = length; /* make it clear that track is no longer than length */ | 129 | intro_length = length; /* make it clear that track is no longer than length */ |
128 | loop_length = 0; | 130 | loop_length = 0; |
131 | id3->tail_trim = 0; | ||
129 | } | 132 | } |
130 | 133 | ||
131 | id3->length = intro_length + 2 * loop_length; /* intro + 2 loops */ | 134 | /* intro + 2 loops + fade */ |
132 | return; | 135 | id3->length = intro_length + 2 * loop_length + id3->tail_trim; |
136 | return; | ||
133 | } | 137 | } |
134 | 138 | ||
135 | id3->length = 150 * 1000; /* 2.5 minutes */ | 139 | id3->length = 150 * 1000 + id3->tail_trim; /* 2.5 minutes + fade */ |
136 | } | 140 | } |
137 | 141 | ||
138 | bool get_vgm_metadata(int fd, struct mp3entry* id3) | 142 | bool get_vgm_metadata(int fd, struct mp3entry* id3) |
@@ -151,7 +155,7 @@ bool get_vgm_metadata(int fd, struct mp3entry* id3) | |||
151 | id3->vbr = false; | 155 | id3->vbr = false; |
152 | id3->filesize = filesize(fd); | 156 | id3->filesize = filesize(fd); |
153 | 157 | ||
154 | id3->bitrate = 706; | 158 | id3->bitrate = 1411; |
155 | id3->frequency = 44100; | 159 | id3->frequency = 44100; |
156 | 160 | ||
157 | /* If file is gzipped, will get metadata later */ | 161 | /* If file is gzipped, will get metadata later */ |