diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2005-06-13 15:26:53 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2005-06-13 15:26:53 +0000 |
commit | d94cba6d0f797a2f34db9bb83296a351678c3ab0 (patch) | |
tree | 33b0942df8cea42a738b3fcf85d464395ffcd511 /apps | |
parent | 7dad7d3a6a7b9c2a972d0426488eed503f39cf72 (diff) | |
download | rockbox-d94cba6d0f797a2f34db9bb83296a351678c3ab0.tar.gz rockbox-d94cba6d0f797a2f34db9bb83296a351678c3ab0.zip |
Forward seeking fixed. Some comments added.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6700 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/playback.c | 44 | ||||
-rw-r--r-- | apps/playback.h | 38 | ||||
-rw-r--r-- | apps/plugins/codecmpa.c | 2 |
3 files changed, 59 insertions, 25 deletions
diff --git a/apps/playback.c b/apps/playback.c index c91a3a8155..df0353b1d6 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -125,19 +125,19 @@ static volatile int buf_widx; | |||
125 | 125 | ||
126 | #define MAX_TRACK 10 | 126 | #define MAX_TRACK 10 |
127 | struct track_info { | 127 | struct track_info { |
128 | struct mp3entry id3; | 128 | struct mp3entry id3; /* TAG metadata */ |
129 | struct mp3info mp3data; | 129 | struct mp3info mp3data; /* MP3 metadata */ |
130 | char *codecbuf; | 130 | char *codecbuf; /* Pointer to codec buffer */ |
131 | size_t codecsize; | 131 | size_t codecsize; /* Codec length in bytes */ |
132 | int codectype; | 132 | int codectype; /* Codec type (example AFMT_MPA_L3) */ |
133 | 133 | ||
134 | volatile char *filebuf; | 134 | off_t filerem; /* Remaining bytes of file NOT in buffer */ |
135 | off_t filerem; | 135 | off_t filesize; /* File total length */ |
136 | off_t filesize; | 136 | off_t filepos; /* Read position of file for next buffer fill */ |
137 | off_t filepos; | 137 | off_t start_pos; /* Position to first bytes of file in buffer */ |
138 | volatile int available; | 138 | volatile int available; /* Available bytes to read from buffer */ |
139 | bool taginfo_ready; | 139 | bool taginfo_ready; /* Is metadata read */ |
140 | int playlist_offset; | 140 | int playlist_offset; /* File location in playlist */ |
141 | }; | 141 | }; |
142 | 142 | ||
143 | /* Track information (count in file buffer, read/write indexes for | 143 | /* Track information (count in file buffer, read/write indexes for |
@@ -286,7 +286,11 @@ void codec_advance_buffer_callback(size_t amount) | |||
286 | 286 | ||
287 | if ((int)amount > cur_ti->available) { | 287 | if ((int)amount > cur_ti->available) { |
288 | codecbufused = 0; | 288 | codecbufused = 0; |
289 | buf_ridx = buf_widx; | 289 | buf_ridx = 0; |
290 | buf_widx = 0; | ||
291 | cur_ti->start_pos += amount; | ||
292 | amount -= cur_ti->available; | ||
293 | ci.curpos += cur_ti->available; | ||
290 | cur_ti->available = 0; | 294 | cur_ti->available = 0; |
291 | while ((int)amount < cur_ti->available && !ci.stop_codec) | 295 | while ((int)amount < cur_ti->available && !ci.stop_codec) |
292 | yield(); | 296 | yield(); |
@@ -343,7 +347,8 @@ bool codec_seek_buffer_callback(off_t newpos) | |||
343 | if (ci.curpos - difference < 0) | 347 | if (ci.curpos - difference < 0) |
344 | difference = ci.curpos; | 348 | difference = ci.curpos; |
345 | 349 | ||
346 | if (codecbufused + difference > codecbuflen) { | 350 | if (ci.curpos - difference < cur_ti->start_pos) { |
351 | logf("Seek failed (reload song)"); | ||
347 | /* We need to reload the song. FIX THIS! */ | 352 | /* We need to reload the song. FIX THIS! */ |
348 | return false; | 353 | return false; |
349 | } | 354 | } |
@@ -473,8 +478,9 @@ void audio_fill_file_buffer(void) | |||
473 | fill_bytesleft -= rc; | 478 | fill_bytesleft -= rc; |
474 | } | 479 | } |
475 | 480 | ||
476 | tracks[track_widx].filerem -= i; | ||
477 | codecbufused += i; | 481 | codecbufused += i; |
482 | tracks[track_widx].filerem -= i; | ||
483 | tracks[track_widx].start_pos = tracks[track_widx].filepos; | ||
478 | tracks[track_widx].filepos += i; | 484 | tracks[track_widx].filepos += i; |
479 | logf("Done:%d", tracks[track_widx].available); | 485 | logf("Done:%d", tracks[track_widx].available); |
480 | if (tracks[track_widx].filerem == 0) { | 486 | if (tracks[track_widx].filerem == 0) { |
@@ -653,7 +659,8 @@ bool audio_load_track(int offset, bool start_play, int peek_offset) | |||
653 | close(fd); | 659 | close(fd); |
654 | return false; | 660 | return false; |
655 | } | 661 | } |
656 | tracks[track_widx].filebuf = &codecbuf[buf_widx]; | 662 | // tracks[track_widx].filebuf = &codecbuf[buf_widx]; |
663 | tracks[track_widx].start_pos = 0; | ||
657 | 664 | ||
658 | //logf("%s", trackname); | 665 | //logf("%s", trackname); |
659 | logf("Buffering track:%d/%d", track_widx, track_ridx); | 666 | logf("Buffering track:%d/%d", track_widx, track_ridx); |
@@ -681,6 +688,7 @@ bool audio_load_track(int offset, bool start_play, int peek_offset) | |||
681 | tracks[track_widx].filepos = offset; | 688 | tracks[track_widx].filepos = offset; |
682 | tracks[track_widx].filerem = tracks[track_widx].filesize - offset; | 689 | tracks[track_widx].filerem = tracks[track_widx].filesize - offset; |
683 | ci.curpos = offset; | 690 | ci.curpos = offset; |
691 | tracks[track_widx].start_pos = offset; | ||
684 | } else { | 692 | } else { |
685 | lseek(fd, 0, SEEK_SET); | 693 | lseek(fd, 0, SEEK_SET); |
686 | } | 694 | } |
@@ -943,7 +951,7 @@ bool audio_load_track(int offset, bool start_play, int peek_offset) | |||
943 | 951 | ||
944 | track_changed = true; | 952 | track_changed = true; |
945 | track_count++; | 953 | track_count++; |
946 | i = tracks[track_widx].filepos; | 954 | i = tracks[track_widx].start_pos; |
947 | while (i < size) { | 955 | while (i < size) { |
948 | /* Give codecs some processing time to prevent glitches. */ | 956 | /* Give codecs some processing time to prevent glitches. */ |
949 | yield_codecs(); | 957 | yield_codecs(); |
diff --git a/apps/playback.h b/apps/playback.h index 18f92488fa..4cdece75c9 100644 --- a/apps/playback.h +++ b/apps/playback.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #ifndef _AUDIO_H | 20 | #ifndef _AUDIO_H |
21 | #define _AUDIO_H | 21 | #define _AUDIO_H |
22 | 22 | ||
23 | /* Supported file types. */ | ||
23 | #define AFMT_MPA_L1 0x0001 // MPEG Audio layer 1 | 24 | #define AFMT_MPA_L1 0x0001 // MPEG Audio layer 1 |
24 | #define AFMT_MPA_L2 0x0002 // MPEG Audio layer 2 | 25 | #define AFMT_MPA_L2 0x0002 // MPEG Audio layer 2 |
25 | #define AFMT_MPA_L3 0x0004 // MPEG Audio layer 3 | 26 | #define AFMT_MPA_L3 0x0004 // MPEG Audio layer 3 |
@@ -36,6 +37,7 @@ | |||
36 | #define AFMT_UNKNOWN 0x1000 // Unknown file format | 37 | #define AFMT_UNKNOWN 0x1000 // Unknown file format |
37 | #define AFMT_WAVPACK 0x2000 // WavPack | 38 | #define AFMT_WAVPACK 0x2000 // WavPack |
38 | 39 | ||
40 | /* File buffer configuration keys. */ | ||
39 | #define CODEC_SET_FILEBUF_WATERMARK 1 | 41 | #define CODEC_SET_FILEBUF_WATERMARK 1 |
40 | #define CODEC_SET_FILEBUF_CHUNKSIZE 2 | 42 | #define CODEC_SET_FILEBUF_CHUNKSIZE 2 |
41 | #define CODEC_SET_FILEBUF_LIMIT 3 | 43 | #define CODEC_SET_FILEBUF_LIMIT 3 |
@@ -43,32 +45,56 @@ | |||
43 | /* Not yet implemented. */ | 45 | /* Not yet implemented. */ |
44 | #define CODEC_SET_AUDIOBUF_WATERMARK 4 | 46 | #define CODEC_SET_AUDIOBUF_WATERMARK 4 |
45 | 47 | ||
48 | /* Codec Interface */ | ||
46 | struct codec_api { | 49 | struct codec_api { |
47 | off_t filesize; | 50 | off_t filesize; /* Total file length */ |
48 | off_t curpos; | 51 | off_t curpos; /* Current buffer position */ |
49 | size_t bitspersampe; | ||
50 | 52 | ||
51 | /* For gapless mp3 */ | 53 | /* For gapless mp3 */ |
52 | struct mp3entry *id3; | 54 | struct mp3entry *id3; /* TAG metadata pointer */ |
53 | struct mp3info *mp3data; | 55 | struct mp3info *mp3data; /* MP3 metadata pointer */ |
54 | bool *taginfo_ready; | 56 | bool *taginfo_ready; /* Is metadata read */ |
55 | 57 | ||
58 | /* Codec should periodically check if stop_codec is set to true. | ||
59 | In case it's, codec must return with PLUGIN_OK status immediately. */ | ||
56 | bool stop_codec; | 60 | bool stop_codec; |
61 | /* Codec should periodically check if reload_codec is set to true. | ||
62 | In case it's, codec should reload itself without exiting. */ | ||
57 | bool reload_codec; | 63 | bool reload_codec; |
64 | /* If seek_time != 0, codec should seek to that song position (in ms) | ||
65 | if codec supports seeking. */ | ||
58 | int seek_time; | 66 | int seek_time; |
59 | 67 | ||
68 | /* Returns buffer to malloc array. Only codeclib should need this. */ | ||
60 | void* (*get_codec_memory)(size_t *size); | 69 | void* (*get_codec_memory)(size_t *size); |
70 | /* Insert PCM data into audio buffer for playback. Playback will start | ||
71 | automatically. */ | ||
61 | bool (*audiobuffer_insert)(char *data, size_t length); | 72 | bool (*audiobuffer_insert)(char *data, size_t length); |
73 | /* Set song position in WPS (value in ms). */ | ||
62 | void (*set_elapsed)(unsigned int value); | 74 | void (*set_elapsed)(unsigned int value); |
63 | 75 | ||
76 | /* Read next <size> amount bytes from file buffer to <ptr>. | ||
77 | Will return number of bytes read or 0 if end of file. */ | ||
64 | size_t (*read_filebuf)(void *ptr, size_t size); | 78 | size_t (*read_filebuf)(void *ptr, size_t size); |
79 | /* Request pointer to file buffer which can be used to read | ||
80 | <realsize> amount of data. <reqsize> tells the buffer system | ||
81 | how much data it should try to allocate. If <realsize> is 0, | ||
82 | end of file is reached. */ | ||
65 | void* (*request_buffer)(size_t *realsize, size_t reqsize); | 83 | void* (*request_buffer)(size_t *realsize, size_t reqsize); |
84 | /* Advance file buffer position by <amount> amount of bytes. */ | ||
66 | void (*advance_buffer)(size_t amount); | 85 | void (*advance_buffer)(size_t amount); |
86 | /* Advance file buffer to a pointer location inside file buffer. */ | ||
67 | void (*advance_buffer_loc)(void *ptr); | 87 | void (*advance_buffer_loc)(void *ptr); |
88 | /* Seek file buffer to position <newpos> beginning of file. */ | ||
68 | bool (*seek_buffer)(off_t newpos); | 89 | bool (*seek_buffer)(off_t newpos); |
90 | /* Calculate mp3 seek position from given time data in ms. */ | ||
69 | off_t (*mp3_get_filepos)(int newtime); | 91 | off_t (*mp3_get_filepos)(int newtime); |
92 | /* Request file change from file buffer. Returns true is next | ||
93 | track is available and changed. If return value is false, | ||
94 | codec should exit immediately with PLUGIN_OK status. */ | ||
70 | bool (*request_next_track)(void); | 95 | bool (*request_next_track)(void); |
71 | 96 | ||
97 | /* Configure different codec buffer parameters. */ | ||
72 | void (*configure)(int setting, void *value); | 98 | void (*configure)(int setting, void *value); |
73 | }; | 99 | }; |
74 | 100 | ||
diff --git a/apps/plugins/codecmpa.c b/apps/plugins/codecmpa.c index b152f2cb3e..67062bc40b 100644 --- a/apps/plugins/codecmpa.c +++ b/apps/plugins/codecmpa.c | |||
@@ -305,12 +305,12 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm) | |||
305 | sample_loc = ci->seek_time/1000 * ci->id3->frequency; | 305 | sample_loc = ci->seek_time/1000 * ci->id3->frequency; |
306 | newpos = ci->mp3_get_filepos(ci->seek_time-1); | 306 | newpos = ci->mp3_get_filepos(ci->seek_time-1); |
307 | if (ci->seek_buffer(newpos)) { | 307 | if (ci->seek_buffer(newpos)) { |
308 | ci->seek_time = 0; | ||
309 | if (sample_loc >= samplecount + samplesdone) | 308 | if (sample_loc >= samplecount + samplesdone) |
310 | break ; | 309 | break ; |
311 | samplecount += samplesdone - sample_loc; | 310 | samplecount += samplesdone - sample_loc; |
312 | samplesdone = sample_loc; | 311 | samplesdone = sample_loc; |
313 | } | 312 | } |
313 | ci->seek_time = 0; | ||
314 | } | 314 | } |
315 | 315 | ||
316 | /* Lock buffers */ | 316 | /* Lock buffers */ |