summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/playback.c67
-rw-r--r--apps/playback.h9
-rw-r--r--apps/plugins/codecflac.c3
-rw-r--r--apps/plugins/codecmpa.c3
-rw-r--r--apps/plugins/codecvorbis.c2
5 files changed, 62 insertions, 22 deletions
diff --git a/apps/playback.c b/apps/playback.c
index 43e45ca3cf..71cb479059 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -67,9 +67,8 @@ static volatile bool paused;
67#define CODEC_FLAC "/.rockbox/codecs/codecflac.rock"; 67#define CODEC_FLAC "/.rockbox/codecs/codecflac.rock";
68#define CODEC_WAV "/.rockbox/codecs/codecwav.rock"; 68#define CODEC_WAV "/.rockbox/codecs/codecwav.rock";
69 69
70#define AUDIO_WATERMARK (1024*256) 70#define AUDIO_DEFAULT_WATERMARK (1024*256)
71#define AUDIO_FILE_CHUNK (1024*32) 71#define AUDIO_DEFAULT_FILECHUNK (1024*32)
72#define AUDIO_INITIAL_CHUNK (1024*1024*2)
73 72
74#define AUDIO_PLAY 1 73#define AUDIO_PLAY 1
75#define AUDIO_STOP 2 74#define AUDIO_STOP 2
@@ -165,8 +164,10 @@ static struct codec_api ci;
165 variable keeps information about whether to go a next/previous track. */ 164 variable keeps information about whether to go a next/previous track. */
166static int new_track; 165static int new_track;
167 166
168/* If we have just started playing, don't fill the whole file buffer. */ 167/* Configuration */
169static unsigned int first_bufferfill; 168static int conf_bufferlimit;
169static int conf_watermark;
170static int conf_filechunk;
170 171
171static bool v1first = false; 172static bool v1first = false;
172 173
@@ -359,6 +360,26 @@ bool codec_seek_buffer_callback(off_t newpos)
359 return true; 360 return true;
360} 361}
361 362
363void codec_configure_callback(int setting, void *value)
364{
365 switch (setting) {
366 case CODEC_SET_FILEBUF_WATERMARK:
367 conf_watermark = (unsigned int)value;
368 break;
369
370 case CODEC_SET_FILEBUF_CHUNKSIZE:
371 conf_filechunk = (unsigned int)value;
372 break;
373
374 case CODEC_SET_FILEBUF_LIMIT:
375 conf_bufferlimit = (unsigned int)value;
376 break;
377
378 default:
379 logf("Illegal key: %d", setting);
380 }
381}
382
362/* Simple file type probing by looking filename extension. */ 383/* Simple file type probing by looking filename extension. */
363int probe_file_format(const char *filename) 384int probe_file_format(const char *filename)
364{ 385{
@@ -431,10 +452,10 @@ void audio_fill_file_buffer(void)
431 return ; 452 return ;
432 } 453 }
433 454
434 if (fill_bytesleft < MIN(AUDIO_FILE_CHUNK, 455 if (fill_bytesleft < MIN((unsigned int)conf_filechunk,
435 tracks[track_widx].filerem - i)) 456 tracks[track_widx].filerem - i))
436 break ; 457 break ;
437 rc = MIN(AUDIO_FILE_CHUNK, codecbuflen - buf_widx); 458 rc = MIN(conf_filechunk, codecbuflen - buf_widx);
438 rc = read(current_fd, &codecbuf[buf_widx], rc); 459 rc = read(current_fd, &codecbuf[buf_widx], rc);
439 if (rc <= 0) { 460 if (rc <= 0) {
440 tracks[track_widx].filerem = 0; 461 tracks[track_widx].filerem = 0;
@@ -535,7 +556,7 @@ bool loadcodec(const char *trackname, bool start_play)
535 } 556 }
536 557
537 size = filesize(fd); 558 size = filesize(fd);
538 if ((off_t)fill_bytesleft < size + AUDIO_WATERMARK) { 559 if ((off_t)fill_bytesleft < size + conf_watermark) {
539 logf("Not enough space"); 560 logf("Not enough space");
540 close(fd); 561 close(fd);
541 return false; 562 return false;
@@ -550,7 +571,7 @@ bool loadcodec(const char *trackname, bool start_play)
550 return false; 571 return false;
551 } 572 }
552 573
553 copy_n = MIN(AUDIO_FILE_CHUNK, codecbuflen - buf_widx); 574 copy_n = MIN(conf_filechunk, codecbuflen - buf_widx);
554 rc = read(fd, &codecbuf[buf_widx], copy_n); 575 rc = read(fd, &codecbuf[buf_widx], copy_n);
555 if (rc < 0) 576 if (rc < 0)
556 return false; 577 return false;
@@ -603,7 +624,14 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
603 /* Load the codec */ 624 /* Load the codec */
604 if (buf_widx >= codecbuflen) 625 if (buf_widx >= codecbuflen)
605 buf_widx -= codecbuflen; 626 buf_widx -= codecbuflen;
606 627
628 /* Set default values */
629 if (start_play) {
630 conf_bufferlimit = 0;
631 conf_watermark = AUDIO_DEFAULT_WATERMARK;
632 conf_filechunk = AUDIO_DEFAULT_FILECHUNK;
633 }
634
607 tracks[track_widx].codecbuf = &codecbuf[buf_widx]; 635 tracks[track_widx].codecbuf = &codecbuf[buf_widx];
608 if (!loadcodec(trackname, start_play)) { 636 if (!loadcodec(trackname, start_play)) {
609 close(fd); 637 close(fd);
@@ -720,18 +748,19 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
720 break; 748 break;
721 } 749 }
722 750
723 /* Limit buffering size at first run. */
724 if (first_bufferfill && fill_bytesleft >= first_bufferfill) {
725 fill_bytesleft = first_bufferfill;
726 first_bufferfill = 0;
727 }
728
729 track_changed = true; 751 track_changed = true;
730 track_count++; 752 track_count++;
731 i = tracks[track_widx].filepos; 753 i = tracks[track_widx].filepos;
732 while (i < size) { 754 while (i < size) {
733 /* Give codecs some processing time to prevent glitches. */ 755 /* Give codecs some processing time to prevent glitches. */
734 yield_codecs(); 756 yield_codecs();
757
758 /* Limit buffering size at first run. */
759 if (conf_bufferlimit && (int)fill_bytesleft >= conf_bufferlimit) {
760 fill_bytesleft = conf_bufferlimit;
761 conf_bufferlimit = 0;
762 }
763
735 if (!queue_empty(&audio_queue)) { 764 if (!queue_empty(&audio_queue)) {
736 logf("Buffering interrupted"); 765 logf("Buffering interrupted");
737 close(fd); 766 close(fd);
@@ -741,7 +770,7 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
741 if (fill_bytesleft == 0) 770 if (fill_bytesleft == 0)
742 break ; 771 break ;
743 772
744 copy_n = MIN(AUDIO_FILE_CHUNK, codecbuflen - buf_widx); 773 copy_n = MIN(conf_filechunk, codecbuflen - buf_widx);
745 copy_n = MIN(size - i, copy_n); 774 copy_n = MIN(size - i, copy_n);
746 copy_n = MIN((int)fill_bytesleft, copy_n); 775 copy_n = MIN((int)fill_bytesleft, copy_n);
747 rc = read(fd, &codecbuf[buf_widx], copy_n); 776 rc = read(fd, &codecbuf[buf_widx], copy_n);
@@ -825,7 +854,7 @@ void audio_check_buffer(void)
825#endif 854#endif
826 855
827 /* Start buffer filling as necessary. */ 856 /* Start buffer filling as necessary. */
828 if (codecbufused > AUDIO_WATERMARK || !queue_empty(&audio_queue) 857 if (codecbufused > conf_watermark || !queue_empty(&audio_queue)
829 || !playing || ci.stop_codec || ci.reload_codec) 858 || !playing || ci.stop_codec || ci.reload_codec)
830 return ; 859 return ;
831 860
@@ -1163,7 +1192,6 @@ void audio_play(int offset)
1163#endif 1192#endif
1164 paused = false; 1193 paused = false;
1165 playing = true; 1194 playing = true;
1166 first_bufferfill = AUDIO_INITIAL_CHUNK;
1167 queue_post(&audio_queue, AUDIO_PLAY, (void *)offset); 1195 queue_post(&audio_queue, AUDIO_PLAY, (void *)offset);
1168} 1196}
1169 1197
@@ -1435,6 +1463,7 @@ void audio_init(void)
1435 ci.mp3_get_filepos = codec_mp3_get_filepos_callback; 1463 ci.mp3_get_filepos = codec_mp3_get_filepos_callback;
1436 ci.seek_buffer = codec_seek_buffer_callback; 1464 ci.seek_buffer = codec_seek_buffer_callback;
1437 ci.set_elapsed = codec_set_elapsed_callback; 1465 ci.set_elapsed = codec_set_elapsed_callback;
1466 ci.configure = codec_configure_callback;
1438 1467
1439 queue_init(&audio_queue); 1468 queue_init(&audio_queue);
1440 queue_init(&codec_queue); 1469 queue_init(&codec_queue);
diff --git a/apps/playback.h b/apps/playback.h
index 6f3c4214a2..c9668bd9a2 100644
--- a/apps/playback.h
+++ b/apps/playback.h
@@ -35,6 +35,13 @@
35#define AFMT_REAL 0x0800 // Realaudio 35#define AFMT_REAL 0x0800 // Realaudio
36#define AFMT_UNKNOWN 0x1000 // Unknown file format 36#define AFMT_UNKNOWN 0x1000 // Unknown file format
37 37
38#define CODEC_SET_FILEBUF_WATERMARK 1
39#define CODEC_SET_FILEBUF_CHUNKSIZE 2
40#define CODEC_SET_FILEBUF_LIMIT 3
41
42/* Not yet implemented. */
43#define CODEC_SET_AUDIOBUF_WATERMARK 4
44
38struct codec_api { 45struct codec_api {
39 off_t filesize; 46 off_t filesize;
40 off_t curpos; 47 off_t curpos;
@@ -60,6 +67,8 @@ struct codec_api {
60 bool (*seek_buffer)(off_t newpos); 67 bool (*seek_buffer)(off_t newpos);
61 off_t (*mp3_get_filepos)(int newtime); 68 off_t (*mp3_get_filepos)(int newtime);
62 bool (*request_next_track)(void); 69 bool (*request_next_track)(void);
70
71 void (*configure)(int setting, void *value);
63}; 72};
64 73
65#endif 74#endif
diff --git a/apps/plugins/codecflac.c b/apps/plugins/codecflac.c
index 8862bbc215..d577006440 100644
--- a/apps/plugins/codecflac.c
+++ b/apps/plugins/codecflac.c
@@ -171,7 +171,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
171 rb->memcpy(iramstart, iramcopy, iramend-iramstart); 171 rb->memcpy(iramstart, iramcopy, iramend-iramstart);
172#endif 172#endif
173 173
174 /* This function sets up the buffers and reads the file into RAM */ 174 ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*10));
175 ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512));
175 176
176 next_track: 177 next_track:
177 178
diff --git a/apps/plugins/codecmpa.c b/apps/plugins/codecmpa.c
index 46014127b8..88f6b8c624 100644
--- a/apps/plugins/codecmpa.c
+++ b/apps/plugins/codecmpa.c
@@ -216,8 +216,9 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
216 216
217 /* Create a decoder instance */ 217 /* Create a decoder instance */
218 218
219 next_track: 219 ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2));
220 220
221 next_track:
221 memset(&Stream, 0, sizeof(struct mad_stream)); 222 memset(&Stream, 0, sizeof(struct mad_stream));
222 memset(&Frame, 0, sizeof(struct mad_frame)); 223 memset(&Frame, 0, sizeof(struct mad_frame));
223 memset(&Synth, 0, sizeof(struct mad_synth)); 224 memset(&Synth, 0, sizeof(struct mad_synth));
diff --git a/apps/plugins/codecvorbis.c b/apps/plugins/codecvorbis.c
index 948482677f..c1ccdfd3fa 100644
--- a/apps/plugins/codecvorbis.c
+++ b/apps/plugins/codecvorbis.c
@@ -104,7 +104,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parm)
104 rb->memcpy(iramstart, iramcopy, iramend-iramstart); 104 rb->memcpy(iramstart, iramcopy, iramend-iramstart);
105 #endif 105 #endif
106 106
107 /* This function sets up the buffers and reads the file into RAM */ 107 ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2));
108 108
109 /* We need to flush reserver memory every track load. */ 109 /* We need to flush reserver memory every track load. */
110 next_track: 110 next_track: