diff options
Diffstat (limited to 'apps/codecs/flac.c')
-rw-r--r-- | apps/codecs/flac.c | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/apps/codecs/flac.c b/apps/codecs/flac.c index 5e392da8e7..880fd69ab2 100644 --- a/apps/codecs/flac.c +++ b/apps/codecs/flac.c | |||
@@ -193,12 +193,12 @@ static bool flac_init(FLACContext* fc, int first_frame_offset) | |||
193 | */ | 193 | */ |
194 | bool flac_seek(FLACContext* fc, uint32_t newsample) { | 194 | bool flac_seek(FLACContext* fc, uint32_t newsample) { |
195 | uint32_t offset; | 195 | uint32_t offset; |
196 | int i; | ||
197 | 196 | ||
198 | if (nseekpoints==0) { | 197 | if (nseekpoints==0) { |
199 | offset=0; | 198 | /* No seekpoints = no seeking */ |
199 | return false; | ||
200 | } else { | 200 | } else { |
201 | i=nseekpoints-1; | 201 | int i=nseekpoints-1; |
202 | while ((i > 0) && (seekpoints[i].sample > newsample)) { | 202 | while ((i > 0) && (seekpoints[i].sample > newsample)) { |
203 | i--; | 203 | i--; |
204 | } | 204 | } |
@@ -210,13 +210,33 @@ bool flac_seek(FLACContext* fc, uint32_t newsample) { | |||
210 | } | 210 | } |
211 | } | 211 | } |
212 | 212 | ||
213 | offset+=fc->metadatalength; | 213 | return ci->seek_buffer(offset+fc->metadatalength); |
214 | } | ||
214 | 215 | ||
215 | if (ci->seek_buffer(offset)) { | 216 | /* A very simple seek implementation - seek to the seekpoint before |
216 | return true; | 217 | the target offset. |
217 | } else { | 218 | |
219 | This needs to be improved to seek with greater accuracy | ||
220 | */ | ||
221 | bool flac_seek_offset(FLACContext* fc, uint32_t offset) { | ||
222 | if (nseekpoints==0) { | ||
223 | /* No seekpoints = no seeking */ | ||
218 | return false; | 224 | return false; |
225 | } else { | ||
226 | offset-=fc->metadatalength; | ||
227 | int i=nseekpoints-1; | ||
228 | while ((i > 0) && (seekpoints[i].offset > offset)) { | ||
229 | i--; | ||
230 | } | ||
231 | |||
232 | if ((i==0) && (seekpoints[i].offset > offset)) { | ||
233 | offset=0; | ||
234 | } else { | ||
235 | offset=seekpoints[i].offset; | ||
236 | } | ||
219 | } | 237 | } |
238 | |||
239 | return ci->seek_buffer(offset+fc->metadatalength); | ||
220 | } | 240 | } |
221 | 241 | ||
222 | /* this is the codec entry point */ | 242 | /* this is the codec entry point */ |
@@ -249,6 +269,9 @@ enum codec_status codec_start(struct codec_api* api) | |||
249 | ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(FLAC_OUTPUT_DEPTH-1)); | 269 | ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(FLAC_OUTPUT_DEPTH-1)); |
250 | 270 | ||
251 | next_track: | 271 | next_track: |
272 | |||
273 | /* Need to save offset for later use (cleared indirectly by flac_init) */ | ||
274 | samplesdone=ci->id3->offset; | ||
252 | 275 | ||
253 | if (codec_init(api)) { | 276 | if (codec_init(api)) { |
254 | LOGF("FLAC: Error initialising codec\n"); | 277 | LOGF("FLAC: Error initialising codec\n"); |
@@ -262,14 +285,18 @@ enum codec_status codec_start(struct codec_api* api) | |||
262 | goto done; | 285 | goto done; |
263 | } | 286 | } |
264 | 287 | ||
265 | while (!*ci->taginfo_ready) | 288 | while (!*ci->taginfo_ready && !ci->stop_codec) |
266 | ci->yield(); | 289 | ci->sleep(1); |
267 | 290 | ||
268 | ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency)); | 291 | ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency)); |
269 | codec_set_replaygain(ci->id3); | 292 | codec_set_replaygain(ci->id3); |
270 | 293 | ||
294 | if (samplesdone) { | ||
295 | flac_seek_offset(&fc, samplesdone); | ||
296 | samplesdone=0; | ||
297 | } | ||
298 | |||
271 | /* The main decoding loop */ | 299 | /* The main decoding loop */ |
272 | samplesdone=0; | ||
273 | frame=0; | 300 | frame=0; |
274 | buf = ci->request_buffer(&bytesleft, MAX_FRAMESIZE); | 301 | buf = ci->request_buffer(&bytesleft, MAX_FRAMESIZE); |
275 | while (bytesleft) { | 302 | while (bytesleft) { |