diff options
Diffstat (limited to 'lib')
36 files changed, 487 insertions, 192 deletions
diff --git a/lib/rbcodec/codecs/a52.c b/lib/rbcodec/codecs/a52.c index 77caaf87c1..da670308b8 100644 --- a/lib/rbcodec/codecs/a52.c +++ b/lib/rbcodec/codecs/a52.c | |||
@@ -150,19 +150,28 @@ enum codec_status codec_run(void) | |||
150 | 150 | ||
151 | samplesdone = 0; | 151 | samplesdone = 0; |
152 | 152 | ||
153 | /* The main decoding loop */ | ||
154 | if (ci->id3->offset) { | 153 | if (ci->id3->offset) { |
155 | if (ci->seek_buffer(ci->id3->offset)) { | 154 | sample_loc = (ci->id3->offset / ci->id3->bytesperframe) * |
156 | samplesdone = (ci->id3->offset / ci->id3->bytesperframe) * | 155 | A52_SAMPLESPERFRAME; |
157 | A52_SAMPLESPERFRAME; | 156 | param = ci->id3->offset; |
158 | ci->set_elapsed(samplesdone/(ci->id3->frequency / 1000)); | 157 | } |
159 | } | 158 | else if (ci->id3->elapsed) { |
159 | sample_loc = ci->id3->elapsed/1000 * ci->id3->frequency; | ||
160 | param = sample_loc/A52_SAMPLESPERFRAME*ci->id3->bytesperframe; | ||
160 | } | 161 | } |
161 | else { | 162 | else { |
162 | ci->seek_buffer(ci->id3->first_frame_offset); | 163 | sample_loc = 0; |
163 | ci->set_elapsed(0); | 164 | param = ci->id3->first_frame_offset; |
165 | } | ||
166 | |||
167 | if (ci->seek_buffer(param)) { | ||
168 | samplesdone = sample_loc; | ||
164 | } | 169 | } |
165 | 170 | ||
171 | ci->set_elapsed(samplesdone/(ci->id3->frequency/1000)); | ||
172 | |||
173 | /* The main decoding loop */ | ||
174 | |||
166 | while (1) { | 175 | while (1) { |
167 | enum codec_command_action action = ci->get_command(¶m); | 176 | enum codec_command_action action = ci->get_command(¶m); |
168 | 177 | ||
@@ -172,7 +181,8 @@ enum codec_status codec_run(void) | |||
172 | if (action == CODEC_ACTION_SEEK_TIME) { | 181 | if (action == CODEC_ACTION_SEEK_TIME) { |
173 | sample_loc = param/1000 * ci->id3->frequency; | 182 | sample_loc = param/1000 * ci->id3->frequency; |
174 | 183 | ||
175 | if (ci->seek_buffer((sample_loc/A52_SAMPLESPERFRAME)*ci->id3->bytesperframe)) { | 184 | if (ci->seek_buffer((sample_loc/A52_SAMPLESPERFRAME)* |
185 | ci->id3->bytesperframe)) { | ||
176 | samplesdone = sample_loc; | 186 | samplesdone = sample_loc; |
177 | ci->set_elapsed(samplesdone/(ci->id3->frequency/1000)); | 187 | ci->set_elapsed(samplesdone/(ci->id3->frequency/1000)); |
178 | } | 188 | } |
diff --git a/lib/rbcodec/codecs/a52_rm.c b/lib/rbcodec/codecs/a52_rm.c index 42868437d8..3f07a43ce9 100644 --- a/lib/rbcodec/codecs/a52_rm.c +++ b/lib/rbcodec/codecs/a52_rm.c | |||
@@ -148,13 +148,15 @@ enum codec_status codec_run(void) | |||
148 | int consumed, packet_offset; | 148 | int consumed, packet_offset; |
149 | int playback_on = -1; | 149 | int playback_on = -1; |
150 | size_t resume_offset; | 150 | size_t resume_offset; |
151 | enum codec_command_action action; | ||
151 | intptr_t param; | 152 | intptr_t param; |
152 | enum codec_command_action action = CODEC_ACTION_NULL; | ||
153 | 153 | ||
154 | if (codec_init()) { | 154 | if (codec_init()) { |
155 | return CODEC_ERROR; | 155 | return CODEC_ERROR; |
156 | } | 156 | } |
157 | 157 | ||
158 | action = CODEC_ACTION_NULL; | ||
159 | param = ci->id3->elapsed; | ||
158 | resume_offset = ci->id3->offset; | 160 | resume_offset = ci->id3->offset; |
159 | 161 | ||
160 | ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); | 162 | ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); |
@@ -171,11 +173,14 @@ enum codec_status codec_run(void) | |||
171 | samplesdone = 0; | 173 | samplesdone = 0; |
172 | 174 | ||
173 | /* check for a mid-track resume and force a seek time accordingly */ | 175 | /* check for a mid-track resume and force a seek time accordingly */ |
174 | if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) { | 176 | if (resume_offset) { |
175 | resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; | 177 | resume_offset -= MIN(resume_offset, rmctx.data_offset + DATA_HEADER_SIZE); |
176 | /* put number of subpackets to skip in resume_offset */ | 178 | /* put number of subpackets to skip in resume_offset */ |
177 | resume_offset /= (rmctx.block_align + PACKET_HEADER_SIZE); | 179 | resume_offset /= (rmctx.block_align + PACKET_HEADER_SIZE); |
178 | param = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate); | 180 | param = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate); |
181 | } | ||
182 | |||
183 | if (param > 0) { | ||
179 | action = CODEC_ACTION_SEEK_TIME; | 184 | action = CODEC_ACTION_SEEK_TIME; |
180 | } | 185 | } |
181 | else { | 186 | else { |
diff --git a/lib/rbcodec/codecs/aac.c b/lib/rbcodec/codecs/aac.c index c9cf737b48..015e332be2 100644 --- a/lib/rbcodec/codecs/aac.c +++ b/lib/rbcodec/codecs/aac.c | |||
@@ -72,6 +72,7 @@ enum codec_status codec_run(void) | |||
72 | uint32_t sbr_fac = 1; | 72 | uint32_t sbr_fac = 1; |
73 | unsigned char c = 0; | 73 | unsigned char c = 0; |
74 | void *ret; | 74 | void *ret; |
75 | enum codec_command_action action; | ||
75 | intptr_t param; | 76 | intptr_t param; |
76 | bool empty_first_frame = false; | 77 | bool empty_first_frame = false; |
77 | 78 | ||
@@ -82,6 +83,8 @@ enum codec_status codec_run(void) | |||
82 | return CODEC_ERROR; | 83 | return CODEC_ERROR; |
83 | } | 84 | } |
84 | 85 | ||
86 | action = CODEC_ACTION_NULL; | ||
87 | param = ci->id3->elapsed; | ||
85 | file_offset = ci->id3->offset; | 88 | file_offset = ci->id3->offset; |
86 | 89 | ||
87 | ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); | 90 | ci->configure(DSP_SET_FREQUENCY, ci->id3->frequency); |
@@ -138,11 +141,16 @@ enum codec_status codec_run(void) | |||
138 | sound_samples_done = 0; | 141 | sound_samples_done = 0; |
139 | } | 142 | } |
140 | NeAACDecPostSeekReset(decoder, i); | 143 | NeAACDecPostSeekReset(decoder, i); |
144 | elapsed_time = (sound_samples_done * 10) / | ||
145 | (ci->id3->frequency / 100); | ||
146 | } else if (param) { | ||
147 | elapsed_time = param; | ||
148 | action = CODEC_ACTION_SEEK_TIME; | ||
141 | } else { | 149 | } else { |
150 | elapsed_time = 0; | ||
142 | sound_samples_done = 0; | 151 | sound_samples_done = 0; |
143 | } | 152 | } |
144 | 153 | ||
145 | elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100); | ||
146 | ci->set_elapsed(elapsed_time); | 154 | ci->set_elapsed(elapsed_time); |
147 | 155 | ||
148 | if (i == 0) | 156 | if (i == 0) |
@@ -152,7 +160,8 @@ enum codec_status codec_run(void) | |||
152 | 160 | ||
153 | /* The main decoding loop */ | 161 | /* The main decoding loop */ |
154 | while (i < demux_res.num_sample_byte_sizes) { | 162 | while (i < demux_res.num_sample_byte_sizes) { |
155 | enum codec_command_action action = ci->get_command(¶m); | 163 | if (action == CODEC_ACTION_NULL) |
164 | action = ci->get_command(¶m); | ||
156 | 165 | ||
157 | if (action == CODEC_ACTION_HALT) | 166 | if (action == CODEC_ACTION_HALT) |
158 | break; | 167 | break; |
@@ -180,6 +189,8 @@ enum codec_status codec_run(void) | |||
180 | ci->seek_complete(); | 189 | ci->seek_complete(); |
181 | } | 190 | } |
182 | 191 | ||
192 | action = CODEC_ACTION_NULL; | ||
193 | |||
183 | /* There can be gaps between chunks, so skip ahead if needed. It | 194 | /* There can be gaps between chunks, so skip ahead if needed. It |
184 | * doesn't seem to happen much, but it probably means that a | 195 | * doesn't seem to happen much, but it probably means that a |
185 | * "proper" file can have chunks out of order. Why one would want | 196 | * "proper" file can have chunks out of order. Why one would want |
diff --git a/lib/rbcodec/codecs/aiff.c b/lib/rbcodec/codecs/aiff.c index 3bedfa5760..9fee781c03 100644 --- a/lib/rbcodec/codecs/aiff.c +++ b/lib/rbcodec/codecs/aiff.c | |||
@@ -99,6 +99,7 @@ enum codec_status codec_run(void) | |||
99 | codec_set_replaygain(ci->id3); | 99 | codec_set_replaygain(ci->id3); |
100 | 100 | ||
101 | /* Need to save offset for later use (cleared indirectly by advance_buffer) */ | 101 | /* Need to save offset for later use (cleared indirectly by advance_buffer) */ |
102 | param = ci->id3->elapsed; | ||
102 | bytesdone = ci->id3->offset; | 103 | bytesdone = ci->id3->offset; |
103 | 104 | ||
104 | /* assume the AIFF header is less than 1024 bytes */ | 105 | /* assume the AIFF header is less than 1024 bytes */ |
@@ -270,10 +271,20 @@ enum codec_status codec_run(void) | |||
270 | ci->advance_buffer(firstblockposn); | 271 | ci->advance_buffer(firstblockposn); |
271 | 272 | ||
272 | /* make sure we're at the correct offset */ | 273 | /* make sure we're at the correct offset */ |
273 | if (bytesdone > (uint32_t) firstblockposn) { | 274 | if (bytesdone > (uint32_t) firstblockposn || param) { |
275 | uint32_t seek_val; | ||
276 | int seek_mode; | ||
277 | |||
278 | if (bytesdone) { | ||
279 | seek_val = bytesdone - MIN((uint32_t) firstblockposn, bytesdone); | ||
280 | seek_mode = PCM_SEEK_POS; | ||
281 | } else { | ||
282 | seek_val = param; | ||
283 | seek_mode = PCM_SEEK_TIME; | ||
284 | } | ||
285 | |||
274 | /* Round down to previous block */ | 286 | /* Round down to previous block */ |
275 | struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn, | 287 | struct pcm_pos *newpos = codec->get_seek_pos(seek_val, seek_mode, NULL); |
276 | PCM_SEEK_POS, NULL); | ||
277 | 288 | ||
278 | if (newpos->pos > format.numbytes) | 289 | if (newpos->pos > format.numbytes) |
279 | return CODEC_OK; | 290 | return CODEC_OK; |
diff --git a/lib/rbcodec/codecs/alac.c b/lib/rbcodec/codecs/alac.c index 5eb6e001f7..a3a5ad43b8 100644 --- a/lib/rbcodec/codecs/alac.c +++ b/lib/rbcodec/codecs/alac.c | |||
@@ -50,7 +50,7 @@ enum codec_status codec_run(void) | |||
50 | demux_res_t demux_res; | 50 | demux_res_t demux_res; |
51 | stream_t input_stream; | 51 | stream_t input_stream; |
52 | uint32_t samplesdone; | 52 | uint32_t samplesdone; |
53 | uint32_t elapsedtime = 0; | 53 | uint32_t elapsedtime; |
54 | int samplesdecoded; | 54 | int samplesdecoded; |
55 | unsigned int i; | 55 | unsigned int i; |
56 | unsigned char* buffer; | 56 | unsigned char* buffer; |
@@ -71,9 +71,9 @@ enum codec_status codec_run(void) | |||
71 | 71 | ||
72 | stream_create(&input_stream,ci); | 72 | stream_create(&input_stream,ci); |
73 | 73 | ||
74 | /* Read from ci->id3->offset before calling qtmovie_read. */ | 74 | /* Read resume info before calling qtmovie_read. */ |
75 | samplesdone = (uint32_t)(((uint64_t)(ci->id3->offset) * ci->id3->frequency) / | 75 | elapsedtime = ci->id3->elapsed; |
76 | (ci->id3->bitrate*128)); | 76 | samplesdone = ci->id3->offset; |
77 | 77 | ||
78 | /* if qtmovie_read returns successfully, the stream is up to | 78 | /* if qtmovie_read returns successfully, the stream is up to |
79 | * the movie data, which can be used directly by the decoder */ | 79 | * the movie data, which can be used directly by the decoder */ |
@@ -87,16 +87,24 @@ enum codec_status codec_run(void) | |||
87 | 87 | ||
88 | /* Set i for first frame, seek to desired sample position for resuming. */ | 88 | /* Set i for first frame, seek to desired sample position for resuming. */ |
89 | i=0; | 89 | i=0; |
90 | if (samplesdone > 0) { | 90 | |
91 | if (m4a_seek(&demux_res, &input_stream, samplesdone, | 91 | if (elapsedtime || samplesdone) { |
92 | if (samplesdone) { | ||
93 | samplesdone = | ||
94 | (uint32_t)((uint64_t)samplesdone*ci->id3->frequency / | ||
95 | (ci->id3->bitrate*128)); | ||
96 | } | ||
97 | else { | ||
98 | samplesdone = (elapsedtime/10) * (ci->id3->frequency/100); | ||
99 | } | ||
100 | |||
101 | if (!m4a_seek(&demux_res, &input_stream, samplesdone, | ||
92 | &samplesdone, (int*) &i)) { | 102 | &samplesdone, (int*) &i)) { |
93 | elapsedtime = (samplesdone * 10) / (ci->id3->frequency / 100); | ||
94 | ci->set_elapsed(elapsedtime); | ||
95 | } else { | ||
96 | samplesdone = 0; | 103 | samplesdone = 0; |
97 | } | 104 | } |
98 | } | 105 | } |
99 | 106 | ||
107 | elapsedtime = (samplesdone*10)/(ci->id3->frequency/100); | ||
100 | ci->set_elapsed(elapsedtime); | 108 | ci->set_elapsed(elapsedtime); |
101 | 109 | ||
102 | /* The main decoding loop */ | 110 | /* The main decoding loop */ |
@@ -106,9 +114,6 @@ enum codec_status codec_run(void) | |||
106 | if (action == CODEC_ACTION_HALT) | 114 | if (action == CODEC_ACTION_HALT) |
107 | break; | 115 | break; |
108 | 116 | ||
109 | /* Request the required number of bytes from the input buffer */ | ||
110 | buffer=ci->request_buffer(&n, ALAC_BYTE_BUFFER_SIZE); | ||
111 | |||
112 | /* Deal with any pending seek requests */ | 117 | /* Deal with any pending seek requests */ |
113 | if (action == CODEC_ACTION_SEEK_TIME) { | 118 | if (action == CODEC_ACTION_SEEK_TIME) { |
114 | if (m4a_seek(&demux_res, &input_stream, | 119 | if (m4a_seek(&demux_res, &input_stream, |
diff --git a/lib/rbcodec/codecs/ape.c b/lib/rbcodec/codecs/ape.c index 577e7b65e2..a6c5254d45 100644 --- a/lib/rbcodec/codecs/ape.c +++ b/lib/rbcodec/codecs/ape.c | |||
@@ -155,6 +155,7 @@ enum codec_status codec_run(void) | |||
155 | int res; | 155 | int res; |
156 | int firstbyte; | 156 | int firstbyte; |
157 | size_t resume_offset; | 157 | size_t resume_offset; |
158 | enum codec_command_action action; | ||
158 | intptr_t param; | 159 | intptr_t param; |
159 | 160 | ||
160 | if (codec_init()) { | 161 | if (codec_init()) { |
@@ -162,8 +163,12 @@ enum codec_status codec_run(void) | |||
162 | return CODEC_ERROR; | 163 | return CODEC_ERROR; |
163 | } | 164 | } |
164 | 165 | ||
166 | action = CODEC_ACTION_NULL; | ||
167 | param = 0; | ||
168 | |||
165 | /* Remember the resume position - when the codec is opened, the | 169 | /* Remember the resume position - when the codec is opened, the |
166 | playback engine will reset it. */ | 170 | playback engine will reset it. */ |
171 | elapsedtime = ci->id3->elapsed; | ||
167 | resume_offset = ci->id3->offset; | 172 | resume_offset = ci->id3->offset; |
168 | 173 | ||
169 | ci->seek_buffer(0); | 174 | ci->seek_buffer(0); |
@@ -213,14 +218,21 @@ enum codec_status codec_run(void) | |||
213 | 218 | ||
214 | ape_resume(&ape_ctx, resume_offset, | 219 | ape_resume(&ape_ctx, resume_offset, |
215 | ¤tframe, &samplesdone, &samplestoskip, &firstbyte); | 220 | ¤tframe, &samplesdone, &samplestoskip, &firstbyte); |
216 | } else { | 221 | elapsedtime = (samplesdone*10)/(ape_ctx.samplerate/100); |
222 | } | ||
223 | else { | ||
217 | currentframe = 0; | 224 | currentframe = 0; |
218 | samplesdone = 0; | 225 | samplesdone = 0; |
219 | samplestoskip = 0; | 226 | samplestoskip = 0; |
220 | firstbyte = 3; /* Take account of the little-endian 32-bit byte ordering */ | 227 | firstbyte = 3; /* Take account of the little-endian 32-bit byte ordering */ |
228 | |||
229 | if (elapsedtime) { | ||
230 | /* Resume by simulated seeking */ | ||
231 | param = elapsedtime; | ||
232 | action = CODEC_ACTION_SEEK_TIME; | ||
233 | } | ||
221 | } | 234 | } |
222 | 235 | ||
223 | elapsedtime = (samplesdone*10)/(ape_ctx.samplerate/100); | ||
224 | ci->set_elapsed(elapsedtime); | 236 | ci->set_elapsed(elapsedtime); |
225 | 237 | ||
226 | /* Initialise the buffer */ | 238 | /* Initialise the buffer */ |
@@ -247,36 +259,44 @@ frame_start: | |||
247 | /* Decode the frame a chunk at a time */ | 259 | /* Decode the frame a chunk at a time */ |
248 | while (nblocks > 0) | 260 | while (nblocks > 0) |
249 | { | 261 | { |
250 | enum codec_command_action action = ci->get_command(¶m); | 262 | if (action == CODEC_ACTION_NULL) |
263 | action = ci->get_command(¶m); | ||
251 | 264 | ||
252 | if (action == CODEC_ACTION_HALT) | 265 | if (action != CODEC_ACTION_NULL) { |
253 | goto done; | 266 | if (action == CODEC_ACTION_HALT) |
267 | goto done; | ||
254 | 268 | ||
255 | /* Deal with any pending seek requests */ | 269 | /* Deal with any pending seek requests */ |
256 | if (action == CODEC_ACTION_SEEK_TIME) | 270 | if (action == CODEC_ACTION_SEEK_TIME) |
257 | { | ||
258 | if (ape_calc_seekpos(&ape_ctx, | ||
259 | (param/10) * (ci->id3->frequency/100), | ||
260 | ¤tframe, | ||
261 | &newfilepos, | ||
262 | &samplestoskip)) | ||
263 | { | 271 | { |
264 | samplesdone = currentframe * ape_ctx.blocksperframe; | 272 | if (ape_calc_seekpos(&ape_ctx, |
265 | 273 | (param/10) * (ci->id3->frequency/100), | |
266 | /* APE's bytestream is weird... */ | 274 | ¤tframe, |
267 | firstbyte = 3 - (newfilepos & 3); | 275 | &newfilepos, |
268 | newfilepos &= ~3; | 276 | &samplestoskip)) |
269 | 277 | { | |
270 | ci->seek_buffer(newfilepos); | 278 | samplesdone = currentframe * ape_ctx.blocksperframe; |
271 | inbuffer = ci->request_buffer(&bytesleft, INPUT_CHUNKSIZE); | 279 | |
280 | /* APE's bytestream is weird... */ | ||
281 | firstbyte = 3 - (newfilepos & 3); | ||
282 | newfilepos &= ~3; | ||
283 | |||
284 | ci->seek_buffer(newfilepos); | ||
285 | inbuffer = ci->request_buffer(&bytesleft, | ||
286 | INPUT_CHUNKSIZE); | ||
287 | |||
288 | elapsedtime = (samplesdone*10)/ | ||
289 | (ape_ctx.samplerate/100); | ||
290 | ci->set_elapsed(elapsedtime); | ||
291 | ci->seek_complete(); | ||
292 | action = CODEC_ACTION_NULL; | ||
293 | goto frame_start; /* Sorry... */ | ||
294 | } | ||
272 | 295 | ||
273 | elapsedtime = (samplesdone*10)/(ape_ctx.samplerate/100); | ||
274 | ci->set_elapsed(elapsedtime); | ||
275 | ci->seek_complete(); | 296 | ci->seek_complete(); |
276 | goto frame_start; /* Sorry... */ | ||
277 | } | 297 | } |
278 | 298 | ||
279 | ci->seek_complete(); | 299 | action = CODEC_ACTION_NULL; |
280 | } | 300 | } |
281 | 301 | ||
282 | blockstodecode = MIN(BLOCKS_PER_LOOP, nblocks); | 302 | blockstodecode = MIN(BLOCKS_PER_LOOP, nblocks); |
diff --git a/lib/rbcodec/codecs/asap.c b/lib/rbcodec/codecs/asap.c index 19b39a44c4..2c350ba450 100644 --- a/lib/rbcodec/codecs/asap.c +++ b/lib/rbcodec/codecs/asap.c | |||
@@ -52,6 +52,8 @@ enum codec_status codec_run(void) | |||
52 | return CODEC_ERROR; | 52 | return CODEC_ERROR; |
53 | } | 53 | } |
54 | 54 | ||
55 | param = ci->id3->elapsed; | ||
56 | |||
55 | codec_set_replaygain(ci->id3); | 57 | codec_set_replaygain(ci->id3); |
56 | 58 | ||
57 | int bytes_done =0; | 59 | int bytes_done =0; |
@@ -86,8 +88,6 @@ enum codec_status codec_run(void) | |||
86 | ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED); | 88 | ci->configure(DSP_SET_STEREO_MODE, STEREO_INTERLEAVED); |
87 | bytesPerSample = 4; | 89 | bytesPerSample = 4; |
88 | } | 90 | } |
89 | /* reset eleapsed */ | ||
90 | ci->set_elapsed(0); | ||
91 | 91 | ||
92 | song = asap.module_info->default_song; | 92 | song = asap.module_info->default_song; |
93 | duration = asap.module_info->durations[song]; | 93 | duration = asap.module_info->durations[song]; |
@@ -100,6 +100,11 @@ enum codec_status codec_run(void) | |||
100 | ASAP_PlaySong(&asap, song, duration); | 100 | ASAP_PlaySong(&asap, song, duration); |
101 | ASAP_MutePokeyChannels(&asap, 0); | 101 | ASAP_MutePokeyChannels(&asap, 0); |
102 | 102 | ||
103 | if (param) | ||
104 | goto resume_start; | ||
105 | |||
106 | ci->set_elapsed(0); | ||
107 | |||
103 | /* The main decoder loop */ | 108 | /* The main decoder loop */ |
104 | while (1) { | 109 | while (1) { |
105 | enum codec_command_action action = ci->get_command(¶m); | 110 | enum codec_command_action action = ci->get_command(¶m); |
@@ -108,6 +113,7 @@ enum codec_status codec_run(void) | |||
108 | break; | 113 | break; |
109 | 114 | ||
110 | if (action == CODEC_ACTION_SEEK_TIME) { | 115 | if (action == CODEC_ACTION_SEEK_TIME) { |
116 | resume_start: | ||
111 | /* New time is ready in param */ | 117 | /* New time is ready in param */ |
112 | 118 | ||
113 | /* seek to pos */ | 119 | /* seek to pos */ |
diff --git a/lib/rbcodec/codecs/atrac3_oma.c b/lib/rbcodec/codecs/atrac3_oma.c index 50f7c8f163..65d9ed8b38 100644 --- a/lib/rbcodec/codecs/atrac3_oma.c +++ b/lib/rbcodec/codecs/atrac3_oma.c | |||
@@ -50,13 +50,15 @@ enum codec_status codec_run(void) | |||
50 | int elapsed = 0; | 50 | int elapsed = 0; |
51 | size_t resume_offset; | 51 | size_t resume_offset; |
52 | intptr_t param; | 52 | intptr_t param; |
53 | enum codec_command_action action = CODEC_ACTION_NULL; | 53 | enum codec_command_action action; |
54 | 54 | ||
55 | if (codec_init()) { | 55 | if (codec_init()) { |
56 | DEBUGF("codec init failed\n"); | 56 | DEBUGF("codec init failed\n"); |
57 | return CODEC_ERROR; | 57 | return CODEC_ERROR; |
58 | } | 58 | } |
59 | 59 | ||
60 | action = CODEC_ACTION_NULL; | ||
61 | param = ci->id3->elapsed; | ||
60 | resume_offset = ci->id3->offset; | 62 | resume_offset = ci->id3->offset; |
61 | 63 | ||
62 | codec_set_replaygain(ci->id3); | 64 | codec_set_replaygain(ci->id3); |
@@ -79,11 +81,13 @@ enum codec_status codec_run(void) | |||
79 | frame_counter = 0; | 81 | frame_counter = 0; |
80 | 82 | ||
81 | /* check for a mid-track resume and force a seek time accordingly */ | 83 | /* check for a mid-track resume and force a seek time accordingly */ |
82 | if(resume_offset > ci->id3->first_frame_offset) { | 84 | if (resume_offset) { |
83 | resume_offset -= ci->id3->first_frame_offset; | 85 | resume_offset -= MIN(resume_offset, ci->id3->first_frame_offset); |
84 | /* calculate resume_offset in frames */ | 86 | /* calculate resume_offset in frames */ |
85 | resume_offset = (int)resume_offset / FRAMESIZE; | 87 | param = (resume_offset/FRAMESIZE) * ((FRAMESIZE * 8)/BITRATE); |
86 | param = (int)resume_offset * ((FRAMESIZE * 8)/BITRATE); | 88 | } |
89 | |||
90 | if ((unsigned long)param) { | ||
87 | action = CODEC_ACTION_SEEK_TIME; | 91 | action = CODEC_ACTION_SEEK_TIME; |
88 | } | 92 | } |
89 | else { | 93 | else { |
@@ -100,11 +104,9 @@ enum codec_status codec_run(void) | |||
100 | if (action == CODEC_ACTION_HALT) | 104 | if (action == CODEC_ACTION_HALT) |
101 | break; | 105 | break; |
102 | 106 | ||
103 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE); | ||
104 | |||
105 | if (action == CODEC_ACTION_SEEK_TIME) { | 107 | if (action == CODEC_ACTION_SEEK_TIME) { |
106 | /* Do not allow seeking beyond the file's length */ | 108 | /* Do not allow seeking beyond the file's length */ |
107 | if ((unsigned) param > ci->id3->length) { | 109 | if ((unsigned long) param > ci->id3->length) { |
108 | ci->set_elapsed(ci->id3->length); | 110 | ci->set_elapsed(ci->id3->length); |
109 | ci->seek_complete(); | 111 | ci->seek_complete(); |
110 | break; | 112 | break; |
@@ -123,7 +125,6 @@ enum codec_status codec_run(void) | |||
123 | seek_frame_offset = (param * BITRATE) / (8 * FRAMESIZE); | 125 | seek_frame_offset = (param * BITRATE) / (8 * FRAMESIZE); |
124 | frame_counter = seek_frame_offset; | 126 | frame_counter = seek_frame_offset; |
125 | ci->seek_buffer(ci->id3->first_frame_offset + seek_frame_offset* FRAMESIZE); | 127 | ci->seek_buffer(ci->id3->first_frame_offset + seek_frame_offset* FRAMESIZE); |
126 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE); | ||
127 | elapsed = param; | 128 | elapsed = param; |
128 | ci->set_elapsed(elapsed); | 129 | ci->set_elapsed(elapsed); |
129 | ci->seek_complete(); | 130 | ci->seek_complete(); |
@@ -131,6 +132,8 @@ enum codec_status codec_run(void) | |||
131 | 132 | ||
132 | action = CODEC_ACTION_NULL; | 133 | action = CODEC_ACTION_NULL; |
133 | 134 | ||
135 | bit_buffer = (uint8_t *) ci->request_buffer(&buff_size, FRAMESIZE); | ||
136 | |||
134 | res = atrac3_decode_frame(FRAMESIZE, &q, &datasize, bit_buffer, FRAMESIZE); | 137 | res = atrac3_decode_frame(FRAMESIZE, &q, &datasize, bit_buffer, FRAMESIZE); |
135 | 138 | ||
136 | if(res != (int)FRAMESIZE) { | 139 | if(res != (int)FRAMESIZE) { |
diff --git a/lib/rbcodec/codecs/atrac3_rm.c b/lib/rbcodec/codecs/atrac3_rm.c index 997507425e..4b528c0a8d 100644 --- a/lib/rbcodec/codecs/atrac3_rm.c +++ b/lib/rbcodec/codecs/atrac3_rm.c | |||
@@ -57,17 +57,19 @@ enum codec_status codec_run(void) | |||
57 | uint8_t *bit_buffer; | 57 | uint8_t *bit_buffer; |
58 | uint16_t fs,sps,h; | 58 | uint16_t fs,sps,h; |
59 | uint32_t packet_count; | 59 | uint32_t packet_count; |
60 | int scrambling_unit_size, num_units, elapsed = 0; | 60 | int scrambling_unit_size, num_units, elapsed; |
61 | int playback_on = -1; | 61 | int playback_on = -1; |
62 | size_t resume_offset; | 62 | size_t resume_offset; |
63 | intptr_t param; | 63 | intptr_t param; |
64 | enum codec_command_action action = CODEC_ACTION_NULL; | 64 | enum codec_command_action action; |
65 | 65 | ||
66 | if (codec_init()) { | 66 | if (codec_init()) { |
67 | DEBUGF("codec init failed\n"); | 67 | DEBUGF("codec init failed\n"); |
68 | return CODEC_ERROR; | 68 | return CODEC_ERROR; |
69 | } | 69 | } |
70 | 70 | ||
71 | action = CODEC_ACTION_NULL; | ||
72 | elapsed = ci->id3->elapsed; | ||
71 | resume_offset = ci->id3->offset; | 73 | resume_offset = ci->id3->offset; |
72 | 74 | ||
73 | codec_set_replaygain(ci->id3); | 75 | codec_set_replaygain(ci->id3); |
@@ -98,15 +100,20 @@ enum codec_status codec_run(void) | |||
98 | } | 100 | } |
99 | 101 | ||
100 | /* check for a mid-track resume and force a seek time accordingly */ | 102 | /* check for a mid-track resume and force a seek time accordingly */ |
101 | if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) { | 103 | if(resume_offset) { |
102 | resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; | 104 | resume_offset -= MIN(resume_offset, rmctx.data_offset + DATA_HEADER_SIZE); |
103 | num_units = (int)resume_offset / scrambling_unit_size; | 105 | num_units = (int)resume_offset / scrambling_unit_size; |
104 | /* put number of subpackets to skip in resume_offset */ | 106 | /* put number of subpackets to skip in resume_offset */ |
105 | resume_offset /= (sps + PACKET_HEADER_SIZE); | 107 | resume_offset /= (sps + PACKET_HEADER_SIZE); |
106 | param = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate); | 108 | elapsed = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate); |
109 | } | ||
110 | |||
111 | if (elapsed > 0) { | ||
112 | param = elapsed; | ||
107 | action = CODEC_ACTION_SEEK_TIME; | 113 | action = CODEC_ACTION_SEEK_TIME; |
108 | } | 114 | } |
109 | else { | 115 | else { |
116 | elapsed = 0; | ||
110 | ci->set_elapsed(0); | 117 | ci->set_elapsed(0); |
111 | } | 118 | } |
112 | 119 | ||
@@ -151,6 +158,7 @@ seek_start : | |||
151 | 158 | ||
152 | /* Seek to the start of the track */ | 159 | /* Seek to the start of the track */ |
153 | if (param == 0) { | 160 | if (param == 0) { |
161 | elapsed = 0; | ||
154 | ci->set_elapsed(0); | 162 | ci->set_elapsed(0); |
155 | ci->seek_complete(); | 163 | ci->seek_complete(); |
156 | action = CODEC_ACTION_NULL; | 164 | action = CODEC_ACTION_NULL; |
diff --git a/lib/rbcodec/codecs/au.c b/lib/rbcodec/codecs/au.c index 7ae7fe3e94..18d4296125 100644 --- a/lib/rbcodec/codecs/au.c +++ b/lib/rbcodec/codecs/au.c | |||
@@ -139,6 +139,7 @@ enum codec_status codec_run(void) | |||
139 | codec_set_replaygain(ci->id3); | 139 | codec_set_replaygain(ci->id3); |
140 | 140 | ||
141 | /* Need to save offset for later use (cleared indirectly by advance_buffer) */ | 141 | /* Need to save offset for later use (cleared indirectly by advance_buffer) */ |
142 | param = ci->id3->elapsed; | ||
142 | bytesdone = ci->id3->offset; | 143 | bytesdone = ci->id3->offset; |
143 | 144 | ||
144 | ci->memset(&format, 0, sizeof(struct pcm_format)); | 145 | ci->memset(&format, 0, sizeof(struct pcm_format)); |
@@ -236,10 +237,20 @@ enum codec_status codec_run(void) | |||
236 | } | 237 | } |
237 | 238 | ||
238 | /* make sure we're at the correct offset */ | 239 | /* make sure we're at the correct offset */ |
239 | if (bytesdone > (uint32_t) firstblockposn) { | 240 | if (bytesdone > (uint32_t) firstblockposn || param) { |
241 | uint32_t seek_val; | ||
242 | int seek_mode; | ||
243 | |||
244 | if (bytesdone) { | ||
245 | seek_val = bytesdone - MIN((uint32_t) firstblockposn, bytesdone); | ||
246 | seek_mode = PCM_SEEK_POS; | ||
247 | } else { | ||
248 | seek_val = param; | ||
249 | seek_mode = PCM_SEEK_TIME; | ||
250 | } | ||
251 | |||
240 | /* Round down to previous block */ | 252 | /* Round down to previous block */ |
241 | struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn, | 253 | struct pcm_pos *newpos = codec->get_seek_pos(seek_val, seek_mode, NULL); |
242 | PCM_SEEK_POS, NULL); | ||
243 | 254 | ||
244 | if (newpos->pos > format.numbytes) | 255 | if (newpos->pos > format.numbytes) |
245 | goto done; | 256 | goto done; |
diff --git a/lib/rbcodec/codecs/ay.c b/lib/rbcodec/codecs/ay.c index b11ad84294..88936df131 100644 --- a/lib/rbcodec/codecs/ay.c +++ b/lib/rbcodec/codecs/ay.c | |||
@@ -56,6 +56,7 @@ enum codec_status codec_run(void) | |||
56 | /* reset values */ | 56 | /* reset values */ |
57 | track = is_multitrack = 0; | 57 | track = is_multitrack = 0; |
58 | elapsed_time = 0; | 58 | elapsed_time = 0; |
59 | param = ci->id3->elapsed; | ||
59 | 60 | ||
60 | DEBUGF("AY: next_track\n"); | 61 | DEBUGF("AY: next_track\n"); |
61 | if (codec_init()) { | 62 | if (codec_init()) { |
@@ -87,6 +88,10 @@ enum codec_status codec_run(void) | |||
87 | is_multitrack = 1; | 88 | is_multitrack = 1; |
88 | } | 89 | } |
89 | 90 | ||
91 | if (param) { | ||
92 | goto resume_start; | ||
93 | } | ||
94 | |||
90 | next_track: | 95 | next_track: |
91 | set_codec_track(track, is_multitrack); | 96 | set_codec_track(track, is_multitrack); |
92 | 97 | ||
@@ -98,6 +103,7 @@ next_track: | |||
98 | break; | 103 | break; |
99 | 104 | ||
100 | if (action == CODEC_ACTION_SEEK_TIME) { | 105 | if (action == CODEC_ACTION_SEEK_TIME) { |
106 | resume_start: | ||
101 | if (is_multitrack) { | 107 | if (is_multitrack) { |
102 | track = param/1000; | 108 | track = param/1000; |
103 | ci->seek_complete(); | 109 | ci->seek_complete(); |
diff --git a/lib/rbcodec/codecs/cook.c b/lib/rbcodec/codecs/cook.c index 55188aad36..402d1d3fa6 100644 --- a/lib/rbcodec/codecs/cook.c +++ b/lib/rbcodec/codecs/cook.c | |||
@@ -56,14 +56,16 @@ enum codec_status codec_run(void) | |||
56 | uint32_t packet_count; | 56 | uint32_t packet_count; |
57 | int scrambling_unit_size, num_units; | 57 | int scrambling_unit_size, num_units; |
58 | size_t resume_offset; | 58 | size_t resume_offset; |
59 | intptr_t param = 0; | 59 | intptr_t param; |
60 | enum codec_command_action action = CODEC_ACTION_NULL; | 60 | enum codec_command_action action; |
61 | 61 | ||
62 | if (codec_init()) { | 62 | if (codec_init()) { |
63 | DEBUGF("codec init failed\n"); | 63 | DEBUGF("codec init failed\n"); |
64 | return CODEC_ERROR; | 64 | return CODEC_ERROR; |
65 | } | 65 | } |
66 | 66 | ||
67 | action = CODEC_ACTION_NULL; | ||
68 | param = ci->id3->elapsed; | ||
67 | resume_offset = ci->id3->offset; | 69 | resume_offset = ci->id3->offset; |
68 | 70 | ||
69 | codec_set_replaygain(ci->id3); | 71 | codec_set_replaygain(ci->id3); |
@@ -97,12 +99,15 @@ enum codec_status codec_run(void) | |||
97 | } | 99 | } |
98 | 100 | ||
99 | /* check for a mid-track resume and force a seek time accordingly */ | 101 | /* check for a mid-track resume and force a seek time accordingly */ |
100 | if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) { | 102 | if(resume_offset) { |
101 | resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; | 103 | resume_offset -= MIN(resume_offset, rmctx.data_offset + DATA_HEADER_SIZE); |
102 | num_units = (int)resume_offset / scrambling_unit_size; | 104 | num_units = (int)resume_offset / scrambling_unit_size; |
103 | /* put number of subpackets to skip in resume_offset */ | 105 | /* put number of subpackets to skip in resume_offset */ |
104 | resume_offset /= (sps + PACKET_HEADER_SIZE); | 106 | resume_offset /= (sps + PACKET_HEADER_SIZE); |
105 | param = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate); | 107 | param = (int)resume_offset * ((sps * 8 * 1000)/rmctx.bit_rate); |
108 | } | ||
109 | |||
110 | if (param) { | ||
106 | action = CODEC_ACTION_SEEK_TIME; | 111 | action = CODEC_ACTION_SEEK_TIME; |
107 | } | 112 | } |
108 | else { | 113 | else { |
diff --git a/lib/rbcodec/codecs/flac.c b/lib/rbcodec/codecs/flac.c index 3390c24a2c..eab6e7c2bc 100644 --- a/lib/rbcodec/codecs/flac.c +++ b/lib/rbcodec/codecs/flac.c | |||
@@ -468,7 +468,8 @@ enum codec_status codec_run(void) | |||
468 | return CODEC_ERROR; | 468 | return CODEC_ERROR; |
469 | } | 469 | } |
470 | 470 | ||
471 | /* Need to save offset for later use (cleared indirectly by flac_init) */ | 471 | /* Need to save resume for later use (cleared indirectly by flac_init) */ |
472 | elapsedtime = ci->id3->elapsed; | ||
472 | samplesdone = ci->id3->offset; | 473 | samplesdone = ci->id3->offset; |
473 | 474 | ||
474 | if (!flac_init(&fc,ci->id3->first_frame_offset)) { | 475 | if (!flac_init(&fc,ci->id3->first_frame_offset)) { |
@@ -481,9 +482,16 @@ enum codec_status codec_run(void) | |||
481 | STEREO_MONO : STEREO_NONINTERLEAVED); | 482 | STEREO_MONO : STEREO_NONINTERLEAVED); |
482 | codec_set_replaygain(ci->id3); | 483 | codec_set_replaygain(ci->id3); |
483 | 484 | ||
484 | flac_seek_offset(&fc, samplesdone); | 485 | if (samplesdone || !elapsedtime) { |
485 | samplesdone=fc.samplenumber+fc.blocksize; | 486 | flac_seek_offset(&fc, samplesdone); |
486 | elapsedtime=((uint64_t)samplesdone*1000)/(ci->id3->frequency); | 487 | samplesdone=fc.samplenumber+fc.blocksize; |
488 | elapsedtime=((uint64_t)samplesdone*1000)/(ci->id3->frequency); | ||
489 | } | ||
490 | else if (!flac_seek(&fc,(uint32_t)((uint64_t)elapsedtime | ||
491 | *ci->id3->frequency/1000))) { | ||
492 | elapsedtime = 0; | ||
493 | } | ||
494 | |||
487 | ci->set_elapsed(elapsedtime); | 495 | ci->set_elapsed(elapsedtime); |
488 | 496 | ||
489 | /* The main decoding loop */ | 497 | /* The main decoding loop */ |
diff --git a/lib/rbcodec/codecs/gbs.c b/lib/rbcodec/codecs/gbs.c index def05ed351..717f56c82f 100644 --- a/lib/rbcodec/codecs/gbs.c +++ b/lib/rbcodec/codecs/gbs.c | |||
@@ -76,6 +76,11 @@ enum codec_status codec_run(void) | |||
76 | if (gbs_emu.m3u.size > 0) | 76 | if (gbs_emu.m3u.size > 0) |
77 | gbs_emu.track_count = gbs_emu.m3u.size; | 77 | gbs_emu.track_count = gbs_emu.m3u.size; |
78 | 78 | ||
79 | if (ci->id3->elapsed) { | ||
80 | track = ci->id3->elapsed/1000; | ||
81 | if (track >= gbs_emu.track_count) return CODEC_OK; | ||
82 | } | ||
83 | |||
79 | next_track: | 84 | next_track: |
80 | set_codec_track(track); | 85 | set_codec_track(track); |
81 | 86 | ||
diff --git a/lib/rbcodec/codecs/hes.c b/lib/rbcodec/codecs/hes.c index 849fd88f12..56f49621c6 100644 --- a/lib/rbcodec/codecs/hes.c +++ b/lib/rbcodec/codecs/hes.c | |||
@@ -76,6 +76,11 @@ enum codec_status codec_run(void) | |||
76 | if (hes_emu.m3u.size > 0) | 76 | if (hes_emu.m3u.size > 0) |
77 | hes_emu.track_count = hes_emu.m3u.size; | 77 | hes_emu.track_count = hes_emu.m3u.size; |
78 | 78 | ||
79 | if (ci->id3->elapsed) { | ||
80 | track = ci->id3->elapsed/1000; | ||
81 | if (track >= hes_emu.track_count) return CODEC_OK; | ||
82 | } | ||
83 | |||
79 | next_track: | 84 | next_track: |
80 | set_codec_track(track); | 85 | set_codec_track(track); |
81 | 86 | ||
diff --git a/lib/rbcodec/codecs/kss.c b/lib/rbcodec/codecs/kss.c index 92efcd4e5f..e6cf866cdd 100644 --- a/lib/rbcodec/codecs/kss.c +++ b/lib/rbcodec/codecs/kss.c | |||
@@ -79,6 +79,11 @@ enum codec_status codec_run(void) | |||
79 | if (kss_emu.m3u.size > 0) | 79 | if (kss_emu.m3u.size > 0) |
80 | kss_emu.track_count = kss_emu.m3u.size; | 80 | kss_emu.track_count = kss_emu.m3u.size; |
81 | 81 | ||
82 | if (ci->id3->elapsed) { | ||
83 | track = ci->id3->elapsed/1000; | ||
84 | if (track >= kss_emu.track_count) return CODEC_OK; | ||
85 | } | ||
86 | |||
82 | next_track: | 87 | next_track: |
83 | set_codec_track(track); | 88 | set_codec_track(track); |
84 | 89 | ||
diff --git a/lib/rbcodec/codecs/mod.c b/lib/rbcodec/codecs/mod.c index 8bb2dc5163..4dd0cde6e5 100644 --- a/lib/rbcodec/codecs/mod.c +++ b/lib/rbcodec/codecs/mod.c | |||
@@ -1319,7 +1319,16 @@ enum codec_status codec_run(void) | |||
1319 | loadmod(modfile); | 1319 | loadmod(modfile); |
1320 | 1320 | ||
1321 | /* The main decoder loop */ | 1321 | /* The main decoder loop */ |
1322 | ci->set_elapsed(0); | 1322 | #if 0 |
1323 | /* Needs to be a bit more elaborate or critical stuff is missed */ | ||
1324 | if (ci->id3->elapsed) { | ||
1325 | modplayer.patterntableposition = ci->id3->elapsed/1000; | ||
1326 | modplayer.currentline = 0; | ||
1327 | } | ||
1328 | #endif | ||
1329 | |||
1330 | ci->set_elapsed(modplayer.patterntableposition*1000); | ||
1331 | |||
1323 | bytesdone = 0; | 1332 | bytesdone = 0; |
1324 | old_patterntableposition = 0; | 1333 | old_patterntableposition = 0; |
1325 | 1334 | ||
diff --git a/lib/rbcodec/codecs/mpa.c b/lib/rbcodec/codecs/mpa.c index 07db248099..ca12087e87 100644 --- a/lib/rbcodec/codecs/mpa.c +++ b/lib/rbcodec/codecs/mpa.c | |||
@@ -346,6 +346,11 @@ enum codec_status codec_run(void) | |||
346 | current_frequency = ci->id3->frequency; | 346 | current_frequency = ci->id3->frequency; |
347 | codec_set_replaygain(ci->id3); | 347 | codec_set_replaygain(ci->id3); |
348 | 348 | ||
349 | if (!ci->id3->offset && ci->id3->elapsed) { | ||
350 | /* Have elapsed time but not offset */ | ||
351 | ci->id3->offset = get_file_pos(ci->id3->elapsed); | ||
352 | } | ||
353 | |||
349 | if (ci->id3->offset) { | 354 | if (ci->id3->offset) { |
350 | ci->seek_buffer(ci->id3->offset); | 355 | ci->seek_buffer(ci->id3->offset); |
351 | set_elapsed(ci->id3); | 356 | set_elapsed(ci->id3); |
diff --git a/lib/rbcodec/codecs/mpc.c b/lib/rbcodec/codecs/mpc.c index 9db40242dc..79f2aa22db 100644 --- a/lib/rbcodec/codecs/mpc.c +++ b/lib/rbcodec/codecs/mpc.c | |||
@@ -108,6 +108,7 @@ enum codec_status codec_run(void) | |||
108 | * sample seek position from the file offset, the sampling frequency and | 108 | * sample seek position from the file offset, the sampling frequency and |
109 | * the bitrate. As the saved position is exactly calculated the reverse way | 109 | * the bitrate. As the saved position is exactly calculated the reverse way |
110 | * there is no loss of information except rounding. */ | 110 | * there is no loss of information except rounding. */ |
111 | elapsed_time = ci->id3->elapsed; | ||
111 | samplesdone = 100 * (((mpc_uint64_t)ci->id3->offset * frequency) / byterate); | 112 | samplesdone = 100 * (((mpc_uint64_t)ci->id3->offset * frequency) / byterate); |
112 | 113 | ||
113 | /* Set up digital signal processing for correct number of channels */ | 114 | /* Set up digital signal processing for correct number of channels */ |
@@ -122,19 +123,24 @@ enum codec_status codec_run(void) | |||
122 | 123 | ||
123 | codec_set_replaygain(ci->id3); | 124 | codec_set_replaygain(ci->id3); |
124 | 125 | ||
125 | /* Resume to saved sample offset. */ | 126 | if (samplesdone > 0 || elapsed_time) |
126 | elapsed_time = 0; | ||
127 | |||
128 | if (samplesdone > 0) | ||
129 | { | 127 | { |
130 | if (mpc_demux_seek_sample(demux, samplesdone) == MPC_STATUS_OK) | 128 | mpc_int64_t new_offset = samplesdone; |
129 | |||
130 | if (new_offset <= 0) | ||
131 | new_offset = (elapsed_time/10)*frequency; /* by time */ | ||
132 | |||
133 | /* Resume to sample offset. */ | ||
134 | if (mpc_demux_seek_sample(demux, new_offset) == MPC_STATUS_OK) | ||
131 | { | 135 | { |
132 | elapsed_time = (samplesdone*10)/frequency; | 136 | samplesdone = new_offset; |
133 | } | 137 | } |
134 | else | 138 | else |
135 | { | 139 | { |
136 | samplesdone = 0; | 140 | samplesdone = 0; |
137 | } | 141 | } |
142 | |||
143 | elapsed_time = (samplesdone*10)/frequency; | ||
138 | } | 144 | } |
139 | 145 | ||
140 | ci->set_elapsed(elapsed_time); | 146 | ci->set_elapsed(elapsed_time); |
diff --git a/lib/rbcodec/codecs/nsf.c b/lib/rbcodec/codecs/nsf.c index 4c5b37c3fa..cbdf8e3ec5 100644 --- a/lib/rbcodec/codecs/nsf.c +++ b/lib/rbcodec/codecs/nsf.c | |||
@@ -57,6 +57,7 @@ enum codec_status codec_run(void) | |||
57 | 57 | ||
58 | track = is_multitrack = 0; | 58 | track = is_multitrack = 0; |
59 | elapsed_time = 0; | 59 | elapsed_time = 0; |
60 | param = ci->id3->elapsed; | ||
60 | 61 | ||
61 | DEBUGF("NSF: next_track\n"); | 62 | DEBUGF("NSF: next_track\n"); |
62 | if (codec_init()) { | 63 | if (codec_init()) { |
@@ -85,6 +86,10 @@ enum codec_status codec_run(void) | |||
85 | 86 | ||
86 | if (nsf_emu.track_count > 1) is_multitrack = 1; | 87 | if (nsf_emu.track_count > 1) is_multitrack = 1; |
87 | 88 | ||
89 | if (param) { | ||
90 | goto resume_start; | ||
91 | } | ||
92 | |||
88 | next_track: | 93 | next_track: |
89 | set_codec_track(track, is_multitrack); | 94 | set_codec_track(track, is_multitrack); |
90 | 95 | ||
@@ -96,6 +101,7 @@ next_track: | |||
96 | break; | 101 | break; |
97 | 102 | ||
98 | if (action == CODEC_ACTION_SEEK_TIME) { | 103 | if (action == CODEC_ACTION_SEEK_TIME) { |
104 | resume_start: | ||
99 | if (is_multitrack) { | 105 | if (is_multitrack) { |
100 | track = param/1000; | 106 | track = param/1000; |
101 | ci->seek_complete(); | 107 | ci->seek_complete(); |
diff --git a/lib/rbcodec/codecs/opus.c b/lib/rbcodec/codecs/opus.c index 15d96ff6fe..2c495aa8d0 100644 --- a/lib/rbcodec/codecs/opus.c +++ b/lib/rbcodec/codecs/opus.c | |||
@@ -314,6 +314,7 @@ enum codec_status codec_main(enum codec_entry_call_reason reason) | |||
314 | enum codec_status codec_run(void) | 314 | enum codec_status codec_run(void) |
315 | { | 315 | { |
316 | int error = CODEC_ERROR; | 316 | int error = CODEC_ERROR; |
317 | enum codec_command_action action; | ||
317 | intptr_t param; | 318 | intptr_t param; |
318 | ogg_sync_state oy; | 319 | ogg_sync_state oy; |
319 | ogg_page og; | 320 | ogg_page og; |
@@ -325,13 +326,17 @@ enum codec_status codec_run(void) | |||
325 | OpusDecoder *st = NULL; | 326 | OpusDecoder *st = NULL; |
326 | OpusHeader header; | 327 | OpusHeader header; |
327 | int ret; | 328 | int ret; |
328 | unsigned long strtoffset = ci->id3->offset; | 329 | unsigned long strtoffset; |
329 | int skip = 0; | 330 | int skip = 0; |
330 | int64_t seek_target; | 331 | int64_t seek_target; |
331 | uint64_t granule_pos; | 332 | uint64_t granule_pos; |
332 | 333 | ||
333 | ogg_malloc_init(); | 334 | ogg_malloc_init(); |
334 | 335 | ||
336 | action = CODEC_ACTION_NULL; | ||
337 | param = ci->id3->elapsed; | ||
338 | strtoffset = ci->id3->offset; | ||
339 | |||
335 | global_stack = 0; | 340 | global_stack = 0; |
336 | 341 | ||
337 | #if defined(CPU_COLDFIRE) | 342 | #if defined(CPU_COLDFIRE) |
@@ -351,28 +356,40 @@ enum codec_status codec_run(void) | |||
351 | ci->seek_buffer(0); | 356 | ci->seek_buffer(0); |
352 | ci->set_elapsed(0); | 357 | ci->set_elapsed(0); |
353 | 358 | ||
359 | if (!strtoffset && param) { | ||
360 | action = CODEC_ACTION_SEEK_TIME; | ||
361 | } | ||
362 | |||
363 | goto next_page; | ||
364 | |||
354 | while (1) { | 365 | while (1) { |
355 | enum codec_command_action action = ci->get_command(¶m); | 366 | if (action == CODEC_ACTION_NULL) |
367 | action = ci->get_command(¶m); | ||
356 | 368 | ||
357 | if (action == CODEC_ACTION_HALT) | 369 | if (action != CODEC_ACTION_NULL) { |
358 | break; | 370 | if (action == CODEC_ACTION_HALT) |
371 | break; | ||
372 | |||
373 | if (action == CODEC_ACTION_SEEK_TIME) { | ||
374 | if (st != NULL) { | ||
375 | /* calculate granule to seek to (including seek rewind) */ | ||
376 | seek_target = (48LL * param) + header.preskip; | ||
377 | skip = MIN(seek_target, SEEK_REWIND); | ||
378 | seek_target -= skip; | ||
359 | 379 | ||
360 | if (action == CODEC_ACTION_SEEK_TIME) { | 380 | LOGF("Opus seek page:%lld,%lld,%ld\n", |
361 | if (st != NULL) { | 381 | seek_target, page_granule, (long)param); |
362 | /* calculate granule to seek to (including seek rewind) */ | 382 | speex_seek_page_granule(seek_target, page_granule, &oy, &os); |
363 | seek_target = (48LL * param) + header.preskip; | 383 | } |
364 | skip = MIN(seek_target, SEEK_REWIND); | ||
365 | seek_target -= skip; | ||
366 | 384 | ||
367 | LOGF("Opus seek page:%lld,%lld,%ld\n", | 385 | ci->set_elapsed(param); |
368 | seek_target, page_granule, (long)param); | 386 | ci->seek_complete(); |
369 | speex_seek_page_granule(seek_target, page_granule, &oy, &os); | ||
370 | } | 387 | } |
371 | 388 | ||
372 | ci->set_elapsed(param); | 389 | action = CODEC_ACTION_NULL; |
373 | ci->seek_complete(); | ||
374 | } | 390 | } |
375 | 391 | ||
392 | next_page: | ||
376 | /*Get the ogg buffer for writing*/ | 393 | /*Get the ogg buffer for writing*/ |
377 | if (get_more_data(&oy) < 1) { | 394 | if (get_more_data(&oy) < 1) { |
378 | goto done; | 395 | goto done; |
diff --git a/lib/rbcodec/codecs/raac.c b/lib/rbcodec/codecs/raac.c index 523560b63e..d2d3531028 100644 --- a/lib/rbcodec/codecs/raac.c +++ b/lib/rbcodec/codecs/raac.c | |||
@@ -63,14 +63,16 @@ enum codec_status codec_run(void) | |||
63 | unsigned char c = 0; /* channels */ | 63 | unsigned char c = 0; /* channels */ |
64 | int playback_on = -1; | 64 | int playback_on = -1; |
65 | size_t resume_offset; | 65 | size_t resume_offset; |
66 | enum codec_command_action action; | ||
66 | intptr_t param; | 67 | intptr_t param; |
67 | enum codec_command_action action = CODEC_ACTION_NULL; | ||
68 | 68 | ||
69 | if (codec_init()) { | 69 | if (codec_init()) { |
70 | DEBUGF("FAAD: Codec init error\n"); | 70 | DEBUGF("FAAD: Codec init error\n"); |
71 | return CODEC_ERROR; | 71 | return CODEC_ERROR; |
72 | } | 72 | } |
73 | 73 | ||
74 | action = CODEC_ACTION_NULL; | ||
75 | param = ci->id3->elapsed; | ||
74 | resume_offset = ci->id3->offset; | 76 | resume_offset = ci->id3->offset; |
75 | 77 | ||
76 | ci->memset(&rmctx,0,sizeof(RMContext)); | 78 | ci->memset(&rmctx,0,sizeof(RMContext)); |
@@ -104,15 +106,21 @@ enum codec_status codec_run(void) | |||
104 | } | 106 | } |
105 | 107 | ||
106 | /* check for a mid-track resume and force a seek time accordingly */ | 108 | /* check for a mid-track resume and force a seek time accordingly */ |
107 | if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) { | 109 | if (resume_offset) { |
108 | resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; | 110 | resume_offset -= MIN(resume_offset, rmctx.data_offset + DATA_HEADER_SIZE); |
109 | /* put number of subpackets to skip in resume_offset */ | 111 | /* put number of subpackets to skip in resume_offset */ |
110 | resume_offset /= (rmctx.block_align + PACKET_HEADER_SIZE); | 112 | resume_offset /= (rmctx.block_align + PACKET_HEADER_SIZE); |
111 | param = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate); | 113 | param = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate); |
114 | } | ||
115 | |||
116 | if (param > 0) { | ||
112 | action = CODEC_ACTION_SEEK_TIME; | 117 | action = CODEC_ACTION_SEEK_TIME; |
113 | } | 118 | } |
114 | ci->set_elapsed(0); | 119 | else { |
115 | ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE); | 120 | /* Seek to the first packet */ |
121 | ci->set_elapsed(0); | ||
122 | ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE); | ||
123 | } | ||
116 | 124 | ||
117 | /* The main decoding loop */ | 125 | /* The main decoding loop */ |
118 | while (1) { | 126 | while (1) { |
@@ -124,7 +132,7 @@ enum codec_status codec_run(void) | |||
124 | 132 | ||
125 | if (action == CODEC_ACTION_SEEK_TIME) { | 133 | if (action == CODEC_ACTION_SEEK_TIME) { |
126 | /* Do not allow seeking beyond the file's length */ | 134 | /* Do not allow seeking beyond the file's length */ |
127 | if ((unsigned) param > ci->id3->length) { | 135 | if ((unsigned long)param > ci->id3->length) { |
128 | ci->set_elapsed(ci->id3->length); | 136 | ci->set_elapsed(ci->id3->length); |
129 | ci->seek_complete(); | 137 | ci->seek_complete(); |
130 | break; | 138 | break; |
@@ -164,6 +172,7 @@ enum codec_status codec_run(void) | |||
164 | 172 | ||
165 | ci->advance_buffer(pkt.length); | 173 | ci->advance_buffer(pkt.length); |
166 | } | 174 | } |
175 | |||
167 | ci->seek_buffer(pkt_offset + rmctx.data_offset + DATA_HEADER_SIZE); | 176 | ci->seek_buffer(pkt_offset + rmctx.data_offset + DATA_HEADER_SIZE); |
168 | buffer = ci->request_buffer(&n,rmctx.audio_framesize + 1000); | 177 | buffer = ci->request_buffer(&n,rmctx.audio_framesize + 1000); |
169 | NeAACDecPostSeekReset(decoder, decoder->frame); | 178 | NeAACDecPostSeekReset(decoder, decoder->frame); |
diff --git a/lib/rbcodec/codecs/sgc.c b/lib/rbcodec/codecs/sgc.c index 348a54a2d3..eb260975c5 100644 --- a/lib/rbcodec/codecs/sgc.c +++ b/lib/rbcodec/codecs/sgc.c | |||
@@ -91,6 +91,11 @@ enum codec_status codec_run(void) | |||
91 | if (sgc_emu.m3u.size > 0) | 91 | if (sgc_emu.m3u.size > 0) |
92 | sgc_emu.track_count = sgc_emu.m3u.size; | 92 | sgc_emu.track_count = sgc_emu.m3u.size; |
93 | 93 | ||
94 | if (ci->id3->elapsed) { | ||
95 | track = ci->id3->elapsed/1000; | ||
96 | if (track >= sgc_emu.track_count) return CODEC_OK; | ||
97 | } | ||
98 | |||
94 | next_track: | 99 | next_track: |
95 | set_codec_track(track); | 100 | set_codec_track(track); |
96 | 101 | ||
diff --git a/lib/rbcodec/codecs/sid.c b/lib/rbcodec/codecs/sid.c index 1a6d04155d..6e39d3f759 100644 --- a/lib/rbcodec/codecs/sid.c +++ b/lib/rbcodec/codecs/sid.c | |||
@@ -1253,6 +1253,7 @@ enum codec_status codec_run(void) | |||
1253 | unsigned char subSongsMax, subSong, song_speed; | 1253 | unsigned char subSongsMax, subSong, song_speed; |
1254 | unsigned char *sidfile = NULL; | 1254 | unsigned char *sidfile = NULL; |
1255 | intptr_t param; | 1255 | intptr_t param; |
1256 | bool resume; | ||
1256 | 1257 | ||
1257 | if (codec_init()) { | 1258 | if (codec_init()) { |
1258 | return CODEC_ERROR; | 1259 | return CODEC_ERROR; |
@@ -1269,15 +1270,10 @@ enum codec_status codec_run(void) | |||
1269 | return CODEC_ERROR; | 1270 | return CODEC_ERROR; |
1270 | } | 1271 | } |
1271 | 1272 | ||
1272 | c64Init(SAMPLE_RATE); | 1273 | param = ci->id3->elapsed; |
1273 | LoadSIDFromMemory(sidfile, &load_addr, &init_addr, &play_addr, | 1274 | resume = param != 0; |
1274 | &subSongsMax, &subSong, &song_speed, (unsigned short)filesize); | ||
1275 | sidPoke(24, 15); /* Turn on full volume */ | ||
1276 | cpuJSR(init_addr, subSong); /* Start the song initialize */ | ||
1277 | 1275 | ||
1278 | 1276 | goto sid_start; | |
1279 | /* Set the elapsed time to the current subsong (in seconds) */ | ||
1280 | ci->set_elapsed(subSong*1000); | ||
1281 | 1277 | ||
1282 | /* The main decoder loop */ | 1278 | /* The main decoder loop */ |
1283 | while (1) { | 1279 | while (1) { |
@@ -1287,20 +1283,26 @@ enum codec_status codec_run(void) | |||
1287 | break; | 1283 | break; |
1288 | 1284 | ||
1289 | if (action == CODEC_ACTION_SEEK_TIME) { | 1285 | if (action == CODEC_ACTION_SEEK_TIME) { |
1286 | sid_start: | ||
1290 | /* New time is ready in param */ | 1287 | /* New time is ready in param */ |
1291 | 1288 | ||
1292 | /* Start playing from scratch */ | 1289 | /* Start playing from scratch */ |
1293 | c64Init(SAMPLE_RATE); | 1290 | c64Init(SAMPLE_RATE); |
1294 | LoadSIDFromMemory(sidfile, &load_addr, &init_addr, &play_addr, | 1291 | LoadSIDFromMemory(sidfile, &load_addr, &init_addr, &play_addr, |
1295 | &subSongsMax, &subSong, &song_speed, (unsigned short)filesize); | 1292 | &subSongsMax, &subSong, &song_speed, |
1293 | (unsigned short)filesize); | ||
1296 | sidPoke(24, 15); /* Turn on full volume */ | 1294 | sidPoke(24, 15); /* Turn on full volume */ |
1297 | subSong = param / 1000; /* Now use the current seek time in seconds as subsong */ | 1295 | if (!resume || (resume && param)) |
1296 | subSong = param / 1000; /* Now use the current seek time in | ||
1297 | seconds as subsong */ | ||
1298 | cpuJSR(init_addr, subSong); /* Start the song initialize */ | 1298 | cpuJSR(init_addr, subSong); /* Start the song initialize */ |
1299 | nSamplesToRender = 0; /* Start the rendering from scratch */ | 1299 | nSamplesToRender = 0; /* Start the rendering from scratch */ |
1300 | 1300 | ||
1301 | /* Set the elapsed time to the current subsong (in seconds) */ | 1301 | /* Set the elapsed time to the current subsong (in seconds) */ |
1302 | ci->set_elapsed(subSong*1000); | 1302 | ci->set_elapsed(subSong*1000); |
1303 | ci->seek_complete(); | 1303 | ci->seek_complete(); |
1304 | |||
1305 | resume = false; | ||
1304 | } | 1306 | } |
1305 | 1307 | ||
1306 | nSamplesRendered = 0; | 1308 | nSamplesRendered = 0; |
diff --git a/lib/rbcodec/codecs/smaf.c b/lib/rbcodec/codecs/smaf.c index d56aa0a860..e4ec6342b2 100644 --- a/lib/rbcodec/codecs/smaf.c +++ b/lib/rbcodec/codecs/smaf.c | |||
@@ -360,7 +360,8 @@ enum codec_status codec_run(void) | |||
360 | 360 | ||
361 | codec_set_replaygain(ci->id3); | 361 | codec_set_replaygain(ci->id3); |
362 | 362 | ||
363 | /* Need to save offset for later use (cleared indirectly by advance_buffer) */ | 363 | /* Need to save resume for later use (cleared indirectly by advance_buffer) */ |
364 | param = ci->id3->elapsed; | ||
364 | bytesdone = ci->id3->offset; | 365 | bytesdone = ci->id3->offset; |
365 | 366 | ||
366 | decodedsamples = 0; | 367 | decodedsamples = 0; |
@@ -408,11 +409,21 @@ enum codec_status codec_run(void) | |||
408 | ci->seek_buffer(firstblockposn); | 409 | ci->seek_buffer(firstblockposn); |
409 | 410 | ||
410 | /* make sure we're at the correct offset */ | 411 | /* make sure we're at the correct offset */ |
411 | if (bytesdone > (uint32_t) firstblockposn) | 412 | if (bytesdone > (uint32_t) firstblockposn || param) { |
412 | { | 413 | uint32_t seek_val; |
414 | int seek_mode; | ||
415 | |||
416 | if (bytesdone) { | ||
417 | seek_val = bytesdone - MIN((uint32_t) firstblockposn, bytesdone); | ||
418 | seek_mode = PCM_SEEK_POS; | ||
419 | } else { | ||
420 | seek_val = param; | ||
421 | seek_mode = PCM_SEEK_TIME; | ||
422 | } | ||
423 | |||
413 | /* Round down to previous block */ | 424 | /* Round down to previous block */ |
414 | struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn, | 425 | struct pcm_pos *newpos = codec->get_seek_pos(seek_val, seek_mode, |
415 | PCM_SEEK_POS, &read_buffer); | 426 | &read_buffer); |
416 | 427 | ||
417 | if (newpos->pos > format.numbytes) | 428 | if (newpos->pos > format.numbytes) |
418 | return CODEC_OK; | 429 | return CODEC_OK; |
diff --git a/lib/rbcodec/codecs/speex.c b/lib/rbcodec/codecs/speex.c index ac3bc963b1..a073151ee2 100644 --- a/lib/rbcodec/codecs/speex.c +++ b/lib/rbcodec/codecs/speex.c | |||
@@ -381,7 +381,6 @@ enum codec_status codec_run(void) | |||
381 | int error = CODEC_ERROR; | 381 | int error = CODEC_ERROR; |
382 | 382 | ||
383 | SpeexBits bits; | 383 | SpeexBits bits; |
384 | int eof = 0; | ||
385 | spx_ogg_sync_state oy; | 384 | spx_ogg_sync_state oy; |
386 | spx_ogg_page og; | 385 | spx_ogg_page og; |
387 | spx_ogg_packet op; | 386 | spx_ogg_packet op; |
@@ -403,9 +402,10 @@ enum codec_status codec_run(void) | |||
403 | int packet_count = 0; | 402 | int packet_count = 0; |
404 | int lookahead; | 403 | int lookahead; |
405 | int headerssize = 0; | 404 | int headerssize = 0; |
406 | unsigned long strtoffset = ci->id3->offset; | 405 | unsigned long strtoffset; |
407 | void *st = NULL; | 406 | void *st = NULL; |
408 | int j = 0; | 407 | int j = 0; |
408 | enum codec_command_action action; | ||
409 | intptr_t param; | 409 | intptr_t param; |
410 | 410 | ||
411 | memset(&bits, 0, sizeof(bits)); | 411 | memset(&bits, 0, sizeof(bits)); |
@@ -416,6 +416,10 @@ enum codec_status codec_run(void) | |||
416 | goto exit; | 416 | goto exit; |
417 | } | 417 | } |
418 | 418 | ||
419 | action = CODEC_ACTION_NULL; | ||
420 | param = ci->id3->elapsed; | ||
421 | strtoffset = ci->id3->offset; | ||
422 | |||
419 | ci->seek_buffer(0); | 423 | ci->seek_buffer(0); |
420 | ci->set_elapsed(0); | 424 | ci->set_elapsed(0); |
421 | 425 | ||
@@ -425,29 +429,39 @@ enum codec_status codec_run(void) | |||
425 | 429 | ||
426 | codec_set_replaygain(ci->id3); | 430 | codec_set_replaygain(ci->id3); |
427 | 431 | ||
428 | eof = 0; | 432 | if (!strtoffset && param) { |
429 | while (!eof) { | 433 | action = CODEC_ACTION_SEEK_TIME; |
430 | enum codec_command_action action = ci->get_command(¶m); | 434 | } |
431 | 435 | ||
432 | if (action == CODEC_ACTION_HALT) | 436 | goto next_page; |
433 | break; | 437 | |
434 | 438 | while (1) { | |
435 | /*seek (seeks to the page before the position) */ | 439 | if (action == CODEC_ACTION_NULL) |
436 | if (action == CODEC_ACTION_SEEK_TIME) { | 440 | action = ci->get_command(¶m); |
437 | if(samplerate!=0&&packet_count>1){ | 441 | |
438 | LOGF("Speex seek page:%lld,%lld,%ld,%lld,%d\n", | 442 | if (action != CODEC_ACTION_NULL) { |
439 | ((spx_int64_t)param/1000) * | 443 | if (action == CODEC_ACTION_HALT) |
440 | (spx_int64_t)samplerate, | 444 | break; |
441 | page_granule, (long)param, | 445 | |
442 | (page_granule/samplerate)*1000, samplerate); | 446 | /*seek (seeks to the page before the position) */ |
443 | 447 | if (action == CODEC_ACTION_SEEK_TIME) { | |
444 | speex_seek_page_granule(((spx_int64_t)param/1000) * | 448 | if(samplerate!=0&&packet_count>1){ |
445 | (spx_int64_t)samplerate, | 449 | LOGF("Speex seek page:%lld,%lld,%ld,%lld,%d\n", |
446 | page_granule, &oy, headerssize); | 450 | ((spx_int64_t)param/1000) * |
451 | (spx_int64_t)samplerate, | ||
452 | page_granule, (long)param, | ||
453 | (page_granule/samplerate)*1000, samplerate); | ||
454 | |||
455 | speex_seek_page_granule(((spx_int64_t)param/1000) * | ||
456 | (spx_int64_t)samplerate, | ||
457 | page_granule, &oy, headerssize); | ||
458 | } | ||
459 | |||
460 | ci->set_elapsed(param); | ||
461 | ci->seek_complete(); | ||
447 | } | 462 | } |
448 | 463 | ||
449 | ci->set_elapsed(param); | 464 | action = CODEC_ACTION_NULL; |
450 | ci->seek_complete(); | ||
451 | } | 465 | } |
452 | 466 | ||
453 | next_page: | 467 | next_page: |
diff --git a/lib/rbcodec/codecs/tta.c b/lib/rbcodec/codecs/tta.c index 564496a14e..b7660a920f 100644 --- a/lib/rbcodec/codecs/tta.c +++ b/lib/rbcodec/codecs/tta.c | |||
@@ -82,10 +82,20 @@ enum codec_status codec_run(void) | |||
82 | decodedsamples = 0; | 82 | decodedsamples = 0; |
83 | endofstream = 0; | 83 | endofstream = 0; |
84 | 84 | ||
85 | if (ci->id3->offset > 0) | 85 | if (ci->id3->offset || ci->id3->elapsed) |
86 | { | 86 | { |
87 | /* Need to save offset for later use (cleared indirectly by advance_buffer) */ | 87 | /* Need to save offset for later use (cleared indirectly by |
88 | new_pos = set_position(ci->id3->offset, TTA_SEEK_POS); | 88 | advance_buffer) */ |
89 | unsigned int pos = ci->id3->offset; | ||
90 | enum tta_seek_type type = TTA_SEEK_POS; | ||
91 | |||
92 | if (!pos) { | ||
93 | pos = ci->id3->elapsed / SEEK_STEP; | ||
94 | type = TTA_SEEK_TIME; | ||
95 | } | ||
96 | |||
97 | new_pos = set_position(pos, type); | ||
98 | |||
89 | if (new_pos >= 0) | 99 | if (new_pos >= 0) |
90 | decodedsamples = new_pos; | 100 | decodedsamples = new_pos; |
91 | } | 101 | } |
diff --git a/lib/rbcodec/codecs/vgm.c b/lib/rbcodec/codecs/vgm.c index 9f2f1b9c5e..126305944f 100644 --- a/lib/rbcodec/codecs/vgm.c +++ b/lib/rbcodec/codecs/vgm.c | |||
@@ -127,7 +127,10 @@ enum codec_status codec_run(void) | |||
127 | 127 | ||
128 | Vgm_start_track(&vgm_emu); | 128 | Vgm_start_track(&vgm_emu); |
129 | 129 | ||
130 | ci->set_elapsed(0); | 130 | if (ci->id3->elapsed != 0) |
131 | Track_seek(&vgm_emu, ci->id3->elapsed); | ||
132 | |||
133 | codec_update_elapsed(); | ||
131 | codec_update_fade(); | 134 | codec_update_fade(); |
132 | 135 | ||
133 | /* The main decoder loop */ | 136 | /* The main decoder loop */ |
diff --git a/lib/rbcodec/codecs/vorbis.c b/lib/rbcodec/codecs/vorbis.c index c09d2cea6d..ca9db9b802 100644 --- a/lib/rbcodec/codecs/vorbis.c +++ b/lib/rbcodec/codecs/vorbis.c | |||
@@ -126,7 +126,6 @@ enum codec_status codec_run(void) | |||
126 | long n; | 126 | long n; |
127 | int current_section; | 127 | int current_section; |
128 | int previous_section; | 128 | int previous_section; |
129 | int eof; | ||
130 | ogg_int64_t vf_offsets[2]; | 129 | ogg_int64_t vf_offsets[2]; |
131 | ogg_int64_t vf_dataoffsets; | 130 | ogg_int64_t vf_dataoffsets; |
132 | ogg_uint32_t vf_serialnos; | 131 | ogg_uint32_t vf_serialnos; |
@@ -193,16 +192,17 @@ enum codec_status codec_run(void) | |||
193 | if (ci->id3->offset) { | 192 | if (ci->id3->offset) { |
194 | ci->seek_buffer(ci->id3->offset); | 193 | ci->seek_buffer(ci->id3->offset); |
195 | ov_raw_seek(&vf, ci->id3->offset); | 194 | ov_raw_seek(&vf, ci->id3->offset); |
196 | ci->set_elapsed(ov_time_tell(&vf)); | ||
197 | ci->set_offset(ov_raw_tell(&vf)); | 195 | ci->set_offset(ov_raw_tell(&vf)); |
198 | } | 196 | } |
199 | else { | 197 | else if (ci->id3->elapsed) { |
200 | ci->set_elapsed(0); | 198 | ov_time_seek(&vf, ci->id3->elapsed); |
201 | } | 199 | } |
202 | 200 | ||
201 | ci->set_elapsed(ov_time_tell(&vf)); | ||
202 | |||
203 | previous_section = -1; | 203 | previous_section = -1; |
204 | eof = 0; | 204 | |
205 | while (!eof) { | 205 | while (1) { |
206 | enum codec_command_action action = ci->get_command(¶m); | 206 | enum codec_command_action action = ci->get_command(¶m); |
207 | 207 | ||
208 | if (action == CODEC_ACTION_HALT) | 208 | if (action == CODEC_ACTION_HALT) |
@@ -230,7 +230,7 @@ enum codec_status codec_run(void) | |||
230 | } | 230 | } |
231 | 231 | ||
232 | if (n == 0) { | 232 | if (n == 0) { |
233 | eof = 1; | 233 | break; |
234 | } else if (n < 0) { | 234 | } else if (n < 0) { |
235 | DEBUGF("Vorbis: Error decoding frame\n"); | 235 | DEBUGF("Vorbis: Error decoding frame\n"); |
236 | } else { | 236 | } else { |
diff --git a/lib/rbcodec/codecs/vox.c b/lib/rbcodec/codecs/vox.c index 66979e2911..d84af24cfc 100644 --- a/lib/rbcodec/codecs/vox.c +++ b/lib/rbcodec/codecs/vox.c | |||
@@ -73,7 +73,8 @@ enum codec_status codec_run(void) | |||
73 | 73 | ||
74 | codec_set_replaygain(ci->id3); | 74 | codec_set_replaygain(ci->id3); |
75 | 75 | ||
76 | /* Need to save offset for later use (cleared indirectly by advance_buffer) */ | 76 | /* Need to save resume for later use (cleared indirectly by advance_buffer) */ |
77 | param = ci->id3->elapsed; | ||
77 | bytesdone = ci->id3->offset; | 78 | bytesdone = ci->id3->offset; |
78 | ci->seek_buffer(0); | 79 | ci->seek_buffer(0); |
79 | 80 | ||
@@ -123,10 +124,21 @@ enum codec_status codec_run(void) | |||
123 | ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO); | 124 | ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO); |
124 | 125 | ||
125 | /* make sure we're at the correct offset */ | 126 | /* make sure we're at the correct offset */ |
126 | if (bytesdone > (uint32_t) firstblockposn) { | 127 | if (bytesdone > (uint32_t) firstblockposn || param) { |
128 | uint32_t seek_val; | ||
129 | int seek_mode; | ||
130 | |||
131 | if (bytesdone) { | ||
132 | seek_val = bytesdone - MIN((uint32_t )firstblockposn, bytesdone); | ||
133 | seek_mode = PCM_SEEK_POS; | ||
134 | } else { | ||
135 | seek_val = param; | ||
136 | seek_mode = PCM_SEEK_TIME; | ||
137 | } | ||
138 | |||
127 | /* Round down to previous block */ | 139 | /* Round down to previous block */ |
128 | struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn, | 140 | struct pcm_pos *newpos = codec->get_seek_pos(seek_val, seek_mode, |
129 | PCM_SEEK_POS, &read_buffer); | 141 | &read_buffer); |
130 | 142 | ||
131 | if (newpos->pos > format.numbytes) { | 143 | if (newpos->pos > format.numbytes) { |
132 | return CODEC_OK; | 144 | return CODEC_OK; |
diff --git a/lib/rbcodec/codecs/wav.c b/lib/rbcodec/codecs/wav.c index cc65ab83b2..3208e2b5b8 100644 --- a/lib/rbcodec/codecs/wav.c +++ b/lib/rbcodec/codecs/wav.c | |||
@@ -182,7 +182,8 @@ enum codec_status codec_run(void) | |||
182 | 182 | ||
183 | codec_set_replaygain(ci->id3); | 183 | codec_set_replaygain(ci->id3); |
184 | 184 | ||
185 | /* Need to save offset for later use (cleared indirectly by advance_buffer) */ | 185 | /* Need to save resume for later use (cleared indirectly by advance_buffer) */ |
186 | param = ci->id3->elapsed; | ||
186 | bytesdone = ci->id3->offset; | 187 | bytesdone = ci->id3->offset; |
187 | 188 | ||
188 | /* get RIFF chunk header */ | 189 | /* get RIFF chunk header */ |
@@ -361,10 +362,21 @@ enum codec_status codec_run(void) | |||
361 | } | 362 | } |
362 | 363 | ||
363 | /* make sure we're at the correct offset */ | 364 | /* make sure we're at the correct offset */ |
364 | if (bytesdone > (uint32_t) firstblockposn) { | 365 | if (bytesdone > (uint32_t) firstblockposn || param) { |
366 | uint32_t seek_val; | ||
367 | int seek_mode; | ||
368 | |||
369 | if (bytesdone) { | ||
370 | seek_val = bytesdone - MIN((uint32_t) firstblockposn, bytesdone); | ||
371 | seek_mode = PCM_SEEK_POS; | ||
372 | } else { | ||
373 | seek_val = param; | ||
374 | seek_mode = PCM_SEEK_TIME; | ||
375 | } | ||
376 | |||
365 | /* Round down to previous block */ | 377 | /* Round down to previous block */ |
366 | struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn, | 378 | struct pcm_pos *newpos = codec->get_seek_pos(seek_val, seek_mode, |
367 | PCM_SEEK_POS, &read_buffer); | 379 | &read_buffer); |
368 | 380 | ||
369 | if (newpos->pos > format.numbytes) | 381 | if (newpos->pos > format.numbytes) |
370 | return CODEC_OK; | 382 | return CODEC_OK; |
diff --git a/lib/rbcodec/codecs/wav64.c b/lib/rbcodec/codecs/wav64.c index 9b3b2d38e4..96e605faad 100644 --- a/lib/rbcodec/codecs/wav64.c +++ b/lib/rbcodec/codecs/wav64.c | |||
@@ -191,6 +191,7 @@ enum codec_status codec_run(void) | |||
191 | codec_set_replaygain(ci->id3); | 191 | codec_set_replaygain(ci->id3); |
192 | 192 | ||
193 | /* Need to save offset for later use (cleared indirectly by advance_buffer) */ | 193 | /* Need to save offset for later use (cleared indirectly by advance_buffer) */ |
194 | param = ci->id3->elapsed; | ||
194 | bytesdone = ci->id3->offset; | 195 | bytesdone = ci->id3->offset; |
195 | 196 | ||
196 | /* get RIFF chunk header */ | 197 | /* get RIFF chunk header */ |
@@ -363,10 +364,22 @@ enum codec_status codec_run(void) | |||
363 | } | 364 | } |
364 | 365 | ||
365 | /* make sure we're at the correct offset */ | 366 | /* make sure we're at the correct offset */ |
366 | if (bytesdone > (uint32_t) firstblockposn) { | 367 | if (bytesdone > (uint32_t) firstblockposn || param) { |
368 | uint32_t seek_val; | ||
369 | int seek_mode; | ||
370 | |||
371 | /* we prefer offset resume */ | ||
372 | if (bytesdone > (uint32_t) firstblockposn) { | ||
373 | seek_val = bytesdone - firstblockposn; | ||
374 | seek_mode = PCM_SEEK_POS; | ||
375 | } else { | ||
376 | seek_val = param; | ||
377 | seek_mode = PCM_SEEK_TIME; | ||
378 | } | ||
379 | |||
367 | /* Round down to previous block */ | 380 | /* Round down to previous block */ |
368 | struct pcm_pos *newpos = codec->get_seek_pos(bytesdone - firstblockposn, | 381 | struct pcm_pos *newpos = codec->get_seek_pos(seek_val, seek_mode, |
369 | PCM_SEEK_POS, &read_buffer); | 382 | &read_buffer); |
370 | 383 | ||
371 | if (newpos->pos > format.numbytes) { | 384 | if (newpos->pos > format.numbytes) { |
372 | return CODEC_OK; | 385 | return CODEC_OK; |
diff --git a/lib/rbcodec/codecs/wavpack.c b/lib/rbcodec/codecs/wavpack.c index c0cdafabac..d9c294397c 100644 --- a/lib/rbcodec/codecs/wavpack.c +++ b/lib/rbcodec/codecs/wavpack.c | |||
@@ -55,12 +55,16 @@ enum codec_status codec_run(void) | |||
55 | int bps; | 55 | int bps; |
56 | */ | 56 | */ |
57 | int nchans, sr_100; | 57 | int nchans, sr_100; |
58 | unsigned long offset; | ||
58 | intptr_t param; | 59 | intptr_t param; |
59 | 60 | ||
60 | if (codec_init()) | 61 | if (codec_init()) |
61 | return CODEC_ERROR; | 62 | return CODEC_ERROR; |
62 | 63 | ||
63 | ci->seek_buffer (ci->id3->offset); | 64 | param = ci->id3->elapsed; |
65 | offset = ci->id3->offset; | ||
66 | |||
67 | ci->seek_buffer (offset); | ||
64 | 68 | ||
65 | /* Create a decoder instance */ | 69 | /* Create a decoder instance */ |
66 | wpc = WavpackOpenFileInput (read_callback, error); | 70 | wpc = WavpackOpenFileInput (read_callback, error); |
@@ -75,7 +79,12 @@ enum codec_status codec_run(void) | |||
75 | ci->configure(DSP_SET_STEREO_MODE, nchans == 2 ? STEREO_INTERLEAVED : STEREO_MONO); | 79 | ci->configure(DSP_SET_STEREO_MODE, nchans == 2 ? STEREO_INTERLEAVED : STEREO_MONO); |
76 | sr_100 = ci->id3->frequency / 100; | 80 | sr_100 = ci->id3->frequency / 100; |
77 | 81 | ||
78 | ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10); | 82 | if (!offset && param) { |
83 | goto resume_start; /* resume by elapsed */ | ||
84 | } | ||
85 | else { | ||
86 | ci->set_elapsed (WavpackGetSampleIndex (wpc) / sr_100 * 10); | ||
87 | } | ||
79 | 88 | ||
80 | /* The main decoder loop */ | 89 | /* The main decoder loop */ |
81 | 90 | ||
@@ -87,6 +96,7 @@ enum codec_status codec_run(void) | |||
87 | break; | 96 | break; |
88 | 97 | ||
89 | if (action == CODEC_ACTION_SEEK_TIME) { | 98 | if (action == CODEC_ACTION_SEEK_TIME) { |
99 | resume_start:; | ||
90 | int curpos_ms = WavpackGetSampleIndex (wpc) / sr_100 * 10; | 100 | int curpos_ms = WavpackGetSampleIndex (wpc) / sr_100 * 10; |
91 | int n, d, skip; | 101 | int n, d, skip; |
92 | 102 | ||
diff --git a/lib/rbcodec/codecs/wma.c b/lib/rbcodec/codecs/wma.c index 9039f81429..9a5e0c71fa 100755 --- a/lib/rbcodec/codecs/wma.c +++ b/lib/rbcodec/codecs/wma.c | |||
@@ -52,13 +52,16 @@ enum codec_status codec_run(void) | |||
52 | int audiobufsize; | 52 | int audiobufsize; |
53 | int packetlength = 0; | 53 | int packetlength = 0; |
54 | int errcount = 0; | 54 | int errcount = 0; |
55 | enum codec_command_action action; | ||
55 | intptr_t param; | 56 | intptr_t param; |
56 | 57 | ||
57 | /* Remember the resume position - when the codec is opened, the | 58 | /* Remember the resume position - when the codec is opened, the |
58 | playback engine will reset it. */ | 59 | playback engine will reset it. */ |
60 | elapsedtime = ci->id3->elapsed; | ||
59 | resume_offset = ci->id3->offset; | 61 | resume_offset = ci->id3->offset; |
60 | 62 | ||
61 | restart_track: | 63 | restart_track: |
64 | action = CODEC_ACTION_NULL; | ||
62 | 65 | ||
63 | /* Proper reset of the decoder context. */ | 66 | /* Proper reset of the decoder context. */ |
64 | memset(&wmadec, 0, sizeof(wmadec)); | 67 | memset(&wmadec, 0, sizeof(wmadec)); |
@@ -78,13 +81,20 @@ restart_track: | |||
78 | return CODEC_ERROR; | 81 | return CODEC_ERROR; |
79 | } | 82 | } |
80 | 83 | ||
81 | if (resume_offset > ci->id3->first_frame_offset) | 84 | if (resume_offset > ci->id3->first_frame_offset || elapsedtime) |
82 | { | 85 | { |
83 | /* Get start of current packet */ | 86 | if (resume_offset) { |
84 | int packet_offset = (resume_offset - ci->id3->first_frame_offset) | 87 | /* Get start of current packet */ |
85 | % wfx.packet_size; | 88 | int packet_offset = (resume_offset - |
86 | ci->seek_buffer(resume_offset - packet_offset); | 89 | MIN(resume_offset, ci->id3->first_frame_offset)) |
87 | elapsedtime = asf_get_timestamp(&i); | 90 | % wfx.packet_size; |
91 | ci->seek_buffer(resume_offset - packet_offset); | ||
92 | elapsedtime = asf_get_timestamp(&i); | ||
93 | } | ||
94 | else { | ||
95 | param = elapsedtime; | ||
96 | action = CODEC_ACTION_SEEK_TIME; | ||
97 | } | ||
88 | } | 98 | } |
89 | else | 99 | else |
90 | { | 100 | { |
@@ -104,7 +114,8 @@ restart_track: | |||
104 | /* The main decoding loop */ | 114 | /* The main decoding loop */ |
105 | while (res >= 0) | 115 | while (res >= 0) |
106 | { | 116 | { |
107 | enum codec_command_action action = ci->get_command(¶m); | 117 | if (action == CODEC_ACTION_NULL) |
118 | action = ci->get_command(¶m); | ||
108 | 119 | ||
109 | if (action != CODEC_ACTION_NULL) { | 120 | if (action != CODEC_ACTION_NULL) { |
110 | 121 | ||
@@ -126,6 +137,7 @@ restart_track: | |||
126 | if (param == 0) { | 137 | if (param == 0) { |
127 | ci->set_elapsed(0); | 138 | ci->set_elapsed(0); |
128 | ci->seek_complete(); | 139 | ci->seek_complete(); |
140 | elapsedtime = 0; | ||
129 | goto restart_track; /* Pretend you never saw this... */ | 141 | goto restart_track; /* Pretend you never saw this... */ |
130 | } | 142 | } |
131 | 143 | ||
@@ -140,6 +152,8 @@ restart_track: | |||
140 | ci->set_elapsed(elapsedtime); | 152 | ci->set_elapsed(elapsedtime); |
141 | ci->seek_complete(); | 153 | ci->seek_complete(); |
142 | } | 154 | } |
155 | |||
156 | action = CODEC_ACTION_NULL; | ||
143 | } | 157 | } |
144 | 158 | ||
145 | errcount = 0; | 159 | errcount = 0; |
diff --git a/lib/rbcodec/codecs/wmapro.c b/lib/rbcodec/codecs/wmapro.c index d99ca1aa9e..f15f36813d 100644 --- a/lib/rbcodec/codecs/wmapro.c +++ b/lib/rbcodec/codecs/wmapro.c | |||
@@ -55,6 +55,8 @@ enum codec_status codec_run(void) | |||
55 | int size; /* Size of the input frame to the decoder */ | 55 | int size; /* Size of the input frame to the decoder */ |
56 | intptr_t param; | 56 | intptr_t param; |
57 | 57 | ||
58 | elapsedtime = ci->id3->elapsed; | ||
59 | |||
58 | restart_track: | 60 | restart_track: |
59 | if (codec_init()) { | 61 | if (codec_init()) { |
60 | LOGF("(WMA PRO) Error: Error initialising codec\n"); | 62 | LOGF("(WMA PRO) Error: Error initialising codec\n"); |
@@ -75,11 +77,17 @@ restart_track: | |||
75 | return CODEC_ERROR; | 77 | return CODEC_ERROR; |
76 | } | 78 | } |
77 | 79 | ||
78 | /* Now advance the file position to the first frame */ | 80 | if (elapsedtime) { |
79 | ci->seek_buffer(ci->id3->first_frame_offset); | 81 | elapsedtime = asf_seek(elapsedtime, &wfx); |
82 | if (elapsedtime < 1) | ||
83 | return CODEC_OK; | ||
84 | } | ||
85 | else { | ||
86 | /* Now advance the file position to the first frame */ | ||
87 | ci->seek_buffer(ci->id3->first_frame_offset); | ||
88 | } | ||
80 | 89 | ||
81 | elapsedtime = 0; | 90 | ci->set_elapsed(elapsedtime); |
82 | ci->set_elapsed(0); | ||
83 | 91 | ||
84 | /* The main decoding loop */ | 92 | /* The main decoding loop */ |
85 | 93 | ||
@@ -95,6 +103,7 @@ restart_track: | |||
95 | if (param == 0) { | 103 | if (param == 0) { |
96 | ci->set_elapsed(0); | 104 | ci->set_elapsed(0); |
97 | ci->seek_complete(); | 105 | ci->seek_complete(); |
106 | elapsedtime = 0; | ||
98 | goto restart_track; /* Pretend you never saw this... */ | 107 | goto restart_track; /* Pretend you never saw this... */ |
99 | } | 108 | } |
100 | 109 | ||
diff --git a/lib/rbcodec/codecs/wmavoice.c b/lib/rbcodec/codecs/wmavoice.c index 214e0737e7..4c89c6dc96 100644 --- a/lib/rbcodec/codecs/wmavoice.c +++ b/lib/rbcodec/codecs/wmavoice.c | |||
@@ -67,7 +67,6 @@ enum codec_status codec_run(void) | |||
67 | { | 67 | { |
68 | uint32_t elapsedtime; | 68 | uint32_t elapsedtime; |
69 | asf_waveformatex_t wfx; /* Holds the stream properties */ | 69 | asf_waveformatex_t wfx; /* Holds the stream properties */ |
70 | size_t resume_offset; | ||
71 | int res; /* Return values from asf_read_packet() and decode_packet() */ | 70 | int res; /* Return values from asf_read_packet() and decode_packet() */ |
72 | uint8_t* audiobuf; /* Pointer to the payload of one wma pro packet */ | 71 | uint8_t* audiobuf; /* Pointer to the payload of one wma pro packet */ |
73 | int audiobufsize; /* Payload size */ | 72 | int audiobufsize; /* Payload size */ |
@@ -76,8 +75,8 @@ enum codec_status codec_run(void) | |||
76 | int pktcnt = 0; /* Count of the packets played */ | 75 | int pktcnt = 0; /* Count of the packets played */ |
77 | intptr_t param; | 76 | intptr_t param; |
78 | 77 | ||
79 | /* Remember the resume position */ | 78 | elapsedtime = ci->id3->elapsed; |
80 | resume_offset = ci->id3->offset; | 79 | |
81 | restart_track: | 80 | restart_track: |
82 | if (codec_init()) { | 81 | if (codec_init()) { |
83 | LOGF("(WMA Voice) Error: Error initialising codec\n"); | 82 | LOGF("(WMA Voice) Error: Error initialising codec\n"); |
@@ -105,13 +104,17 @@ restart_track: | |||
105 | return CODEC_ERROR; | 104 | return CODEC_ERROR; |
106 | } | 105 | } |
107 | 106 | ||
108 | /* Now advance the file position to the first frame */ | 107 | if (elapsedtime) { |
109 | ci->seek_buffer(ci->id3->first_frame_offset); | 108 | elapsedtime = asf_seek(elapsedtime, &wfx); |
110 | 109 | if (elapsedtime < 1) | |
111 | elapsedtime = 0; | 110 | return CODEC_OK; |
112 | ci->set_elapsed(0); | 111 | } |
112 | else { | ||
113 | /* Now advance the file position to the first frame */ | ||
114 | ci->seek_buffer(ci->id3->first_frame_offset); | ||
115 | } | ||
113 | 116 | ||
114 | resume_offset = 0; | 117 | ci->set_elapsed(elapsedtime); |
115 | 118 | ||
116 | /* The main decoding loop */ | 119 | /* The main decoding loop */ |
117 | 120 | ||
@@ -129,6 +132,7 @@ restart_track: | |||
129 | if (param == 0) { | 132 | if (param == 0) { |
130 | ci->set_elapsed(0); | 133 | ci->set_elapsed(0); |
131 | ci->seek_complete(); | 134 | ci->seek_complete(); |
135 | elapsedtime = 0; | ||
132 | goto restart_track; /* Pretend you never saw this... */ | 136 | goto restart_track; /* Pretend you never saw this... */ |
133 | } | 137 | } |
134 | 138 | ||
@@ -136,7 +140,7 @@ restart_track: | |||
136 | if (elapsedtime < 1){ | 140 | if (elapsedtime < 1){ |
137 | ci->set_elapsed(0); | 141 | ci->set_elapsed(0); |
138 | ci->seek_complete(); | 142 | ci->seek_complete(); |
139 | goto next_track; | 143 | break; |
140 | } | 144 | } |
141 | 145 | ||
142 | ci->set_elapsed(elapsedtime); | 146 | ci->set_elapsed(elapsedtime); |