summaryrefslogtreecommitdiff
path: root/apps/playback.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/playback.c')
-rw-r--r--apps/playback.c67
1 files changed, 48 insertions, 19 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);