summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/codecs.c2
-rw-r--r--apps/codecs.h18
-rw-r--r--apps/codecs/flac.c8
-rw-r--r--apps/pcmbuf.c15
-rw-r--r--apps/playback.c184
-rw-r--r--apps/playback.h22
6 files changed, 125 insertions, 124 deletions
diff --git a/apps/codecs.c b/apps/codecs.c
index 804dd2e4e5..298e5e1964 100644
--- a/apps/codecs.c
+++ b/apps/codecs.c
@@ -143,6 +143,7 @@ struct codec_api ci = {
143 strncasecmp, 143 strncasecmp,
144 memset, 144 memset,
145 memcpy, 145 memcpy,
146 memmove,
146 _ctype_, 147 _ctype_,
147 atoi, 148 atoi,
148 strchr, 149 strchr,
@@ -215,7 +216,6 @@ struct codec_api ci = {
215 /* new stuff at the end, sort into place next time 216 /* new stuff at the end, sort into place next time
216 the API gets incompatible */ 217 the API gets incompatible */
217 218
218 memmove,
219}; 219};
220 220
221int codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap, 221int codec_load_ram(char* codecptr, int size, void* ptr2, int bufwrap,
diff --git a/apps/codecs.h b/apps/codecs.h
index 7a0fab297f..d28afc7292 100644
--- a/apps/codecs.h
+++ b/apps/codecs.h
@@ -85,12 +85,12 @@
85#define CODEC_MAGIC 0x52434F44 /* RCOD */ 85#define CODEC_MAGIC 0x52434F44 /* RCOD */
86 86
87/* increase this every time the api struct changes */ 87/* increase this every time the api struct changes */
88#define CODEC_API_VERSION 4 88#define CODEC_API_VERSION 5
89 89
90/* update this to latest version if a change to the api struct breaks 90/* update this to latest version if a change to the api struct breaks
91 backwards compatibility (and please take the opportunity to sort in any 91 backwards compatibility (and please take the opportunity to sort in any
92 new function which are "waiting" at the end of the function table) */ 92 new function which are "waiting" at the end of the function table) */
93#define CODEC_MIN_API_VERSION 3 93#define CODEC_MIN_API_VERSION 5
94 94
95/* codec return codes */ 95/* codec return codes */
96enum codec_status { 96enum codec_status {
@@ -125,7 +125,7 @@ struct codec_api {
125 long seek_time; 125 long seek_time;
126 126
127 /* Returns buffer to malloc array. Only codeclib should need this. */ 127 /* Returns buffer to malloc array. Only codeclib should need this. */
128 void* (*get_codec_memory)(long *size); 128 void* (*get_codec_memory)(size_t *size);
129 /* Insert PCM data into audio buffer for playback. Playback will start 129 /* Insert PCM data into audio buffer for playback. Playback will start
130 automatically. */ 130 automatically. */
131 bool (*pcmbuf_insert)(const char *data, size_t length); 131 bool (*pcmbuf_insert)(const char *data, size_t length);
@@ -135,18 +135,18 @@ struct codec_api {
135 135
136 /* Read next <size> amount bytes from file buffer to <ptr>. 136 /* Read next <size> amount bytes from file buffer to <ptr>.
137 Will return number of bytes read or 0 if end of file. */ 137 Will return number of bytes read or 0 if end of file. */
138 long (*read_filebuf)(void *ptr, long size); 138 size_t (*read_filebuf)(void *ptr, size_t size);
139 /* Request pointer to file buffer which can be used to read 139 /* Request pointer to file buffer which can be used to read
140 <realsize> amount of data. <reqsize> tells the buffer system 140 <realsize> amount of data. <reqsize> tells the buffer system
141 how much data it should try to allocate. If <realsize> is 0, 141 how much data it should try to allocate. If <realsize> is 0,
142 end of file is reached. */ 142 end of file is reached. */
143 void* (*request_buffer)(long *realsize, long reqsize); 143 void* (*request_buffer)(size_t *realsize, size_t reqsize);
144 /* Advance file buffer position by <amount> amount of bytes. */ 144 /* Advance file buffer position by <amount> amount of bytes. */
145 void (*advance_buffer)(long amount); 145 void (*advance_buffer)(size_t amount);
146 /* Advance file buffer to a pointer location inside file buffer. */ 146 /* Advance file buffer to a pointer location inside file buffer. */
147 void (*advance_buffer_loc)(void *ptr); 147 void (*advance_buffer_loc)(void *ptr);
148 /* Seek file buffer to position <newpos> beginning of file. */ 148 /* Seek file buffer to position <newpos> beginning of file. */
149 bool (*seek_buffer)(off_t newpos); 149 bool (*seek_buffer)(size_t newpos);
150 /* Codec should call this function when it has done the seeking. */ 150 /* Codec should call this function when it has done the seeking. */
151 void (*seek_complete)(void); 151 void (*seek_complete)(void);
152 /* Calculate mp3 seek position from given time data in ms. */ 152 /* Calculate mp3 seek position from given time data in ms. */
@@ -156,7 +156,7 @@ struct codec_api {
156 codec should exit immediately with PLUGIN_OK status. */ 156 codec should exit immediately with PLUGIN_OK status. */
157 bool (*request_next_track)(void); 157 bool (*request_next_track)(void);
158 158
159 void (*set_offset)(unsigned int value); 159 void (*set_offset)(size_t value);
160 /* Configure different codec buffer parameters. */ 160 /* Configure different codec buffer parameters. */
161 void (*configure)(int setting, void *value); 161 void (*configure)(int setting, void *value);
162 162
@@ -214,6 +214,7 @@ struct codec_api {
214 int (*strncasecmp)(const char *s1, const char *s2, size_t n); 214 int (*strncasecmp)(const char *s1, const char *s2, size_t n);
215 void* (*memset)(void *dst, int c, size_t length); 215 void* (*memset)(void *dst, int c, size_t length);
216 void* (*memcpy)(void *out, const void *in, size_t n); 216 void* (*memcpy)(void *out, const void *in, size_t n);
217 void* (*memmove)(void *out, const void *in, size_t n);
217 const char *_ctype_; 218 const char *_ctype_;
218 int (*atoi)(const char *str); 219 int (*atoi)(const char *str);
219 char *(*strchr)(const char *s, int c); 220 char *(*strchr)(const char *s, int c);
@@ -292,7 +293,6 @@ struct codec_api {
292 /* new stuff at the end, sort into place next time 293 /* new stuff at the end, sort into place next time
293 the API gets incompatible */ 294 the API gets incompatible */
294 295
295 void* (*memmove)(void *out, const void *in, size_t n);
296}; 296};
297 297
298/* codec header */ 298/* codec header */
diff --git a/apps/codecs/flac.c b/apps/codecs/flac.c
index fa263c1095..f95ae2a8ce 100644
--- a/apps/codecs/flac.c
+++ b/apps/codecs/flac.c
@@ -118,11 +118,9 @@ static bool flac_init(FLACContext* fc, int first_frame_offset)
118 118
119 if ((buf[0] & 0x7f) == 0) /* 0 is the STREAMINFO block */ 119 if ((buf[0] & 0x7f) == 0) /* 0 is the STREAMINFO block */
120 { 120 {
121 /* FIXME: Don't trust the value of blocklength */ 121 /* FIXME: Don't trust the value of blocklength, use actual return
122 if (ci->read_filebuf(buf, blocklength) < 0) 122 * value in bytes instead */
123 { 123 ci->read_filebuf(buf, blocklength);
124 return false;
125 }
126 124
127 fc->filesize = ci->filesize; 125 fc->filesize = ci->filesize;
128 fc->min_blocksize = (buf[0] << 8) | buf[1]; 126 fc->min_blocksize = (buf[0] << 8) | buf[1];
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index 6a8e2f2607..2d61f238b6 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -401,8 +401,6 @@ void pcmbuf_pause(bool pause) {
401/* Force playback. */ 401/* Force playback. */
402void pcmbuf_play_start(void) 402void pcmbuf_play_start(void)
403{ 403{
404 mutex_lock(&pcmbuf_mutex);
405
406 if (!pcm_is_playing() && pcmbuf_unplayed_bytes) 404 if (!pcm_is_playing() && pcmbuf_unplayed_bytes)
407 { 405 {
408 /** Prevent a very tiny pop from happening by muting audio 406 /** Prevent a very tiny pop from happening by muting audio
@@ -417,8 +415,6 @@ void pcmbuf_play_start(void)
417 /* Now unmute the audio. */ 415 /* Now unmute the audio. */
418 pcm_mute(false); 416 pcm_mute(false);
419 } 417 }
420
421 mutex_unlock(&pcmbuf_mutex);
422} 418}
423 419
424/** 420/**
@@ -426,27 +422,22 @@ void pcmbuf_play_start(void)
426 */ 422 */
427static void pcmbuf_flush_fillpos(void) 423static void pcmbuf_flush_fillpos(void)
428{ 424{
429 mutex_lock(&pcmbuf_mutex);
430
431 if (audiobuffer_fillpos) { 425 if (audiobuffer_fillpos) {
432 /* Never use the last buffer descriptor */ 426 /* Never use the last buffer descriptor */
433 while (pcmbuf_write == pcmbuf_write_end) { 427 while (pcmbuf_write == pcmbuf_write_end) {
434 logf("pcmbuf_flush_fillpos no descriptors"); 428 logf("pcmbuf_flush_fillpos no descriptors");
435 /* Deboost to let the playback catchup */ 429 /* Deboost to let the playback catchup */
436 pcmbuf_boost(false); 430 pcmbuf_boost(false);
437 /* Let someone else have fun in the meantime */ 431 /* If this happens, something is being stupid */
438 sleep(1);
439 /* This is a fatal error situation that should never happen. */
440 if (!pcm_is_playing()) { 432 if (!pcm_is_playing()) {
441 logf("pcmbuf_flush_fillpos error"); 433 logf("pcmbuf_flush_fillpos error");
442 pcmbuf_play_start(); 434 pcmbuf_play_start();
443 return ;
444 } 435 }
436 /* Let approximately one chunk of data playback */
437 sleep(PCMBUF_TARGET_CHUNK/(NATIVE_FREQUENCY * 4) / 5);
445 } 438 }
446 pcmbuf_add_chunk(); 439 pcmbuf_add_chunk();
447 } 440 }
448
449 mutex_unlock(&pcmbuf_mutex);
450} 441}
451 442
452/** 443/**
diff --git a/apps/playback.c b/apps/playback.c
index 0c04057593..bf6e5bc4be 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -145,7 +145,7 @@ static struct mutex mutex_codecthread;
145static struct mp3entry id3_voice; 145static struct mp3entry id3_voice;
146 146
147static char *voicebuf; 147static char *voicebuf;
148static int voice_remaining; 148static size_t voice_remaining;
149static bool voice_is_playing; 149static bool voice_is_playing;
150static void (*voice_getmore)(unsigned char** start, int* size); 150static void (*voice_getmore)(unsigned char** start, int* size);
151 151
@@ -159,14 +159,14 @@ extern unsigned char codecbuf[];
159static char *filebuf; 159static char *filebuf;
160 160
161/* Total size of the ring buffer. */ 161/* Total size of the ring buffer. */
162int filebuflen; 162size_t filebuflen;
163 163
164/* Bytes available in the buffer. */ 164/* Bytes available in the buffer. */
165int filebufused; 165size_t filebufused;
166 166
167/* Ring buffer read and write indexes. */ 167/* Ring buffer read and write indexes. */
168static volatile int buf_ridx; 168static volatile size_t buf_ridx;
169static volatile int buf_widx; 169static volatile size_t buf_widx;
170 170
171#ifndef SIMULATOR 171#ifndef SIMULATOR
172static unsigned char *iram_buf[2]; 172static unsigned char *iram_buf[2];
@@ -187,7 +187,7 @@ static bool track_changed;
187static int current_fd; 187static int current_fd;
188 188
189/* Information about how many bytes left on the buffer re-fill run. */ 189/* Information about how many bytes left on the buffer re-fill run. */
190static long fill_bytesleft; 190static size_t fill_bytesleft;
191 191
192/* Track info structure about songs in the file buffer. */ 192/* Track info structure about songs in the file buffer. */
193static struct track_info tracks[MAX_TRACK]; 193static struct track_info tracks[MAX_TRACK];
@@ -215,10 +215,10 @@ void (*track_unbuffer_callback)(struct mp3entry *id3, bool last_track);
215static void playback_init(void); 215static void playback_init(void);
216 216
217/* Configuration */ 217/* Configuration */
218static int conf_bufferlimit; 218static size_t conf_bufferlimit;
219static int conf_watermark; 219static size_t conf_watermark;
220static int conf_filechunk; 220static size_t conf_filechunk;
221static int buffer_margin; 221static size_t buffer_margin;
222 222
223static bool v1first = false; 223static bool v1first = false;
224 224
@@ -388,7 +388,7 @@ bool codec_pcmbuf_insert_callback(const char *buf, size_t length)
388 length); 388 length);
389} 389}
390 390
391void* get_codec_memory_callback(long *size) 391void* get_codec_memory_callback(size_t *size)
392{ 392{
393 *size = MALLOC_BUFSIZE; 393 *size = MALLOC_BUFSIZE;
394 if (voice_codec_loaded) 394 if (voice_codec_loaded)
@@ -413,7 +413,8 @@ void codec_set_elapsed_callback(unsigned int value)
413{ 413{
414 unsigned int latency; 414 unsigned int latency;
415 415
416 if (ci.stop_codec || current_codec == CODEC_IDX_VOICE) 416 /* We don't save or display offsets for voice */
417 if (current_codec == CODEC_IDX_VOICE)
417 return ; 418 return ;
418 419
419#ifdef AB_REPEAT_ENABLE 420#ifdef AB_REPEAT_ENABLE
@@ -429,11 +430,12 @@ void codec_set_elapsed_callback(unsigned int value)
429 } 430 }
430} 431}
431 432
432void codec_set_offset_callback(unsigned int value) 433void codec_set_offset_callback(size_t value)
433{ 434{
434 unsigned int latency; 435 unsigned int latency;
435 436
436 if (ci.stop_codec || current_codec == CODEC_IDX_VOICE) 437 /* We don't save or display offsets for voice */
438 if (current_codec == CODEC_IDX_VOICE)
437 return ; 439 return ;
438 440
439 latency = pcmbuf_get_latency() * cur_ti->id3.bitrate / 8; 441 latency = pcmbuf_get_latency() * cur_ti->id3.bitrate / 8;
@@ -445,43 +447,56 @@ void codec_set_offset_callback(unsigned int value)
445 } 447 }
446} 448}
447 449
448long codec_filebuf_callback(void *ptr, long size) 450static void advance_buffer_counters(size_t amount) {
451 buf_ridx += amount;
452 if (buf_ridx >= filebuflen)
453 buf_ridx -= filebuflen;
454 ci.curpos += amount;
455 cur_ti->available -= amount;
456 filebufused -= amount;
457}
458
459/* copy up-to size bytes into ptr and return the actual size copied */
460size_t codec_filebuf_callback(void *ptr, size_t size)
449{ 461{
450 char *buf = (char *)ptr; 462 char *buf = (char *)ptr;
451 int copy_n; 463 size_t copy_n;
452 int part_n; 464 size_t part_n;
453 465
454 if (ci.stop_codec || !playing || current_codec == CODEC_IDX_VOICE) 466 if (ci.stop_codec || !playing || current_codec == CODEC_IDX_VOICE)
455 return 0; 467 return 0;
456 468
457 copy_n = MIN((off_t)size, (off_t)cur_ti->available + cur_ti->filerem); 469 /* The ammount to copy is the lesser of the requested amount and the
470 * amount left of the current track (both on disk and already loaded) */
471 copy_n = MIN(size, cur_ti->available + cur_ti->filerem);
458 472
473 /* Nothing requested OR nothing left */
474 if (copy_n == 0)
475 return 0;
476
477 /* Let the disk buffer catch fill until enough data is available */
459 while (copy_n > cur_ti->available) { 478 while (copy_n > cur_ti->available) {
460 yield(); 479 yield();
461 if (ci.stop_codec || ci.reload_codec) 480 if (ci.stop_codec || ci.reload_codec)
462 return 0; 481 return 0;
463 } 482 }
464 483
465 if (copy_n == 0) 484 /* Copy as much as possible without wrapping */
466 return 0;
467
468 part_n = MIN(copy_n, filebuflen - buf_ridx); 485 part_n = MIN(copy_n, filebuflen - buf_ridx);
469 memcpy(buf, &filebuf[buf_ridx], part_n); 486 memcpy(buf, &filebuf[buf_ridx], part_n);
487 /* Copy the rest in the case of a wrap */
470 if (part_n < copy_n) { 488 if (part_n < copy_n) {
471 memcpy(&buf[part_n], &filebuf[0], copy_n - part_n); 489 memcpy(&buf[part_n], &filebuf[0], copy_n - part_n);
472 } 490 }
473 491
474 buf_ridx += copy_n; 492 /* Update read and other position pointers */
475 if (buf_ridx >= filebuflen) 493 advance_buffer_counters(copy_n);
476 buf_ridx -= filebuflen;
477 ci.curpos += copy_n;
478 cur_ti->available -= copy_n;
479 filebufused -= copy_n;
480 494
495 /* Return the actual amount of data copied to the buffer */
481 return copy_n; 496 return copy_n;
482} 497}
483 498
484void* voice_request_data(long *realsize, long reqsize) 499void* voice_request_data(size_t *realsize, size_t reqsize)
485{ 500{
486 while (queue_empty(&voice_codec_queue) && (voice_remaining == 0 501 while (queue_empty(&voice_codec_queue) && (voice_remaining == 0
487 || voicebuf == NULL) && !ci_voice.stop_codec) 502 || voicebuf == NULL) && !ci_voice.stop_codec)
@@ -503,10 +518,8 @@ void* voice_request_data(long *realsize, long reqsize)
503 if (voice_remaining) 518 if (voice_remaining)
504 { 519 {
505 voice_is_playing = true; 520 voice_is_playing = true;
506 break ;
507 } 521 }
508 522 else if (voice_getmore != NULL)
509 if (voice_getmore != NULL)
510 { 523 {
511 voice_getmore((unsigned char **)&voicebuf, (int *)&voice_remaining); 524 voice_getmore((unsigned char **)&voicebuf, (int *)&voice_remaining);
512 525
@@ -519,13 +532,8 @@ void* voice_request_data(long *realsize, long reqsize)
519 } 532 }
520 } 533 }
521 534
522 if (reqsize < 0)
523 reqsize = 0;
524
525 voice_is_playing = true; 535 voice_is_playing = true;
526 *realsize = voice_remaining; 536 *realsize = MIN(voice_remaining, reqsize);
527 if (*realsize > reqsize)
528 *realsize = reqsize;
529 537
530 if (*realsize == 0) 538 if (*realsize == 0)
531 return NULL; 539 return NULL;
@@ -533,9 +541,9 @@ void* voice_request_data(long *realsize, long reqsize)
533 return voicebuf; 541 return voicebuf;
534} 542}
535 543
536void* codec_request_buffer_callback(long *realsize, long reqsize) 544void* codec_request_buffer_callback(size_t *realsize, size_t reqsize)
537{ 545{
538 long part_n; 546 size_t short_n, copy_n, buf_rem;
539 547
540 /* Voice codec. */ 548 /* Voice codec. */
541 if (current_codec == CODEC_IDX_VOICE) { 549 if (current_codec == CODEC_IDX_VOICE) {
@@ -547,12 +555,13 @@ void* codec_request_buffer_callback(long *realsize, long reqsize)
547 return NULL; 555 return NULL;
548 } 556 }
549 557
550 *realsize = MIN((off_t)reqsize, (off_t)cur_ti->available + cur_ti->filerem); 558 copy_n = MIN(reqsize, cur_ti->available + cur_ti->filerem);
551 if (*realsize == 0) { 559 if (copy_n == 0) {
560 *realsize = 0;
552 return NULL; 561 return NULL;
553 } 562 }
554 563
555 while ((int)*realsize > cur_ti->available) { 564 while (copy_n > cur_ti->available) {
556 yield(); 565 yield();
557 if (ci.stop_codec || ci.reload_codec) { 566 if (ci.stop_codec || ci.reload_codec) {
558 *realsize = 0; 567 *realsize = 0;
@@ -560,19 +569,24 @@ void* codec_request_buffer_callback(long *realsize, long reqsize)
560 } 569 }
561 } 570 }
562 571
563 part_n = MIN((int)*realsize, filebuflen - buf_ridx); 572 /* How much is left at the end of the file buffer before wrap? */
564 if (part_n < *realsize) { 573 buf_rem = filebuflen - buf_ridx;
565 part_n += GUARD_BUFSIZE; 574 /* If we can't satisfy the request without wrapping */
566 if (part_n < *realsize) 575 if (buf_rem < copy_n) {
567 *realsize = part_n; 576 /* How short are we? */
568 memcpy(&filebuf[filebuflen], &filebuf[0], *realsize - 577 short_n = copy_n - buf_rem;
569 (filebuflen - buf_ridx)); 578 /* If we can fudge it with the guardbuf */
579 if (short_n < GUARD_BUFSIZE)
580 memcpy(&filebuf[filebuflen], &filebuf[0], short_n);
581 else
582 copy_n = buf_rem;
570 } 583 }
571 584
585 *realsize = copy_n;
572 return (char *)&filebuf[buf_ridx]; 586 return (char *)&filebuf[buf_ridx];
573} 587}
574 588
575static bool rebuffer_and_seek(int newpos) 589static bool rebuffer_and_seek(size_t newpos)
576{ 590{
577 int fd; 591 int fd;
578 592
@@ -613,11 +627,11 @@ static bool rebuffer_and_seek(int newpos)
613 return true; 627 return true;
614} 628}
615 629
616void codec_advance_buffer_callback(long amount) 630void codec_advance_buffer_callback(size_t amount)
617{ 631{
618 if (current_codec == CODEC_IDX_VOICE) { 632 if (current_codec == CODEC_IDX_VOICE) {
619 //logf("voice ad.buf:%d", amount); 633 //logf("voice ad.buf:%d", amount);
620 amount = MAX(0, MIN(amount, voice_remaining)); 634 amount = MIN(amount, voice_remaining);
621 voicebuf += amount; 635 voicebuf += amount;
622 voice_remaining -= amount; 636 voice_remaining -= amount;
623 637
@@ -636,23 +650,19 @@ void codec_advance_buffer_callback(long amount)
636 return ; 650 return ;
637 } 651 }
638 652
639 buf_ridx += amount; 653 advance_buffer_counters(amount);
640 if (buf_ridx >= filebuflen) 654
641 buf_ridx -= filebuflen;
642 cur_ti->available -= amount;
643 filebufused -= amount;
644 ci.curpos += amount;
645 codec_set_offset_callback(ci.curpos); 655 codec_set_offset_callback(ci.curpos);
646} 656}
647 657
648void codec_advance_buffer_loc_callback(void *ptr) 658void codec_advance_buffer_loc_callback(void *ptr)
649{ 659{
650 long amount; 660 size_t amount;
651 661
652 if (current_codec == CODEC_IDX_VOICE) 662 if (current_codec == CODEC_IDX_VOICE)
653 amount = (long)ptr - (long)voicebuf; 663 amount = (size_t)ptr - (size_t)voicebuf;
654 else 664 else
655 amount = (long)ptr - (long)&filebuf[buf_ridx]; 665 amount = (size_t)ptr - (size_t)&filebuf[buf_ridx];
656 codec_advance_buffer_callback(amount); 666 codec_advance_buffer_callback(amount);
657} 667}
658 668
@@ -672,16 +682,13 @@ void codec_seek_complete_callback(void)
672 ci.seek_time = 0; 682 ci.seek_time = 0;
673} 683}
674 684
675bool codec_seek_buffer_callback(off_t newpos) 685bool codec_seek_buffer_callback(size_t newpos)
676{ 686{
677 int difference; 687 int difference;
678 688
679 if (current_codec == CODEC_IDX_VOICE) 689 if (current_codec == CODEC_IDX_VOICE)
680 return false; 690 return false;
681 691
682 if (newpos < 0)
683 newpos = 0;
684
685 if (newpos >= cur_ti->filesize) 692 if (newpos >= cur_ti->filesize)
686 newpos = cur_ti->filesize - 1; 693 newpos = cur_ti->filesize - 1;
687 694
@@ -706,9 +713,9 @@ bool codec_seek_buffer_callback(off_t newpos)
706 logf("seek: -%d", difference); 713 logf("seek: -%d", difference);
707 filebufused += difference; 714 filebufused += difference;
708 cur_ti->available += difference; 715 cur_ti->available += difference;
716 if (buf_ridx < (unsigned)difference)
717 buf_ridx += filebuflen;
709 buf_ridx -= difference; 718 buf_ridx -= difference;
710 if (buf_ridx < 0)
711 buf_ridx = filebuflen + buf_ridx;
712 ci.curpos -= difference; 719 ci.curpos -= difference;
713 720
714 return true; 721 return true;
@@ -716,7 +723,7 @@ bool codec_seek_buffer_callback(off_t newpos)
716 723
717static void set_filebuf_watermark(int seconds) 724static void set_filebuf_watermark(int seconds)
718{ 725{
719 long bytes; 726 size_t bytes;
720 727
721 if (current_codec == CODEC_IDX_VOICE) 728 if (current_codec == CODEC_IDX_VOICE)
722 return ; 729 return ;
@@ -724,7 +731,7 @@ static void set_filebuf_watermark(int seconds)
724 if (!filebuf) 731 if (!filebuf)
725 return; /* Audio buffers not yet set up */ 732 return; /* Audio buffers not yet set up */
726 733
727 bytes = MAX((int)cur_ti->id3.bitrate * seconds * (1000/8), conf_watermark); 734 bytes = MAX(cur_ti->id3.bitrate * seconds * (1000/8), conf_watermark);
728 bytes = MIN(bytes, filebuflen / 2); 735 bytes = MIN(bytes, filebuflen / 2);
729 conf_watermark = bytes; 736 conf_watermark = bytes;
730} 737}
@@ -803,14 +810,15 @@ void strip_id3v1_tag(void)
803{ 810{
804 int i; 811 int i;
805 static const unsigned char tag[] = "TAG"; 812 static const unsigned char tag[] = "TAG";
806 int tagptr; 813 size_t tagptr;
807 bool found = true; 814 bool found = true;
808 815
809 if (filebufused >= 128) 816 if (filebufused >= 128)
810 { 817 {
811 tagptr = buf_widx - 128; 818 if (buf_widx < 128)
812 if (tagptr < 0) 819 tagptr = filebuflen + buf_widx - 128;
813 tagptr += filebuflen; 820 else
821 tagptr = buf_widx - 128;
814 822
815 for(i = 0;i < 3;i++) 823 for(i = 0;i < 3;i++)
816 { 824 {
@@ -839,7 +847,9 @@ void strip_id3v1_tag(void)
839 847
840static void audio_fill_file_buffer(void) 848static void audio_fill_file_buffer(void)
841{ 849{
842 long i, size; 850 unsigned long i;
851 size_t size;
852 size_t copy_n;
843 int rc; 853 int rc;
844 854
845 if (current_fd < 0) 855 if (current_fd < 0)
@@ -858,9 +868,9 @@ static void audio_fill_file_buffer(void)
858 868
859 if (fill_bytesleft == 0) 869 if (fill_bytesleft == 0)
860 break ; 870 break ;
861 rc = MIN(conf_filechunk, filebuflen - buf_widx); 871 copy_n = MIN(conf_filechunk, filebuflen - buf_widx);
862 rc = MIN(rc, fill_bytesleft); 872 copy_n = MIN(copy_n, fill_bytesleft);
863 rc = read(current_fd, &filebuf[buf_widx], rc); 873 rc = read(current_fd, &filebuf[buf_widx], copy_n);
864 if (rc <= 0) { 874 if (rc <= 0) {
865 tracks[track_widx].filerem = 0; 875 tracks[track_widx].filerem = 0;
866 break ; 876 break ;
@@ -901,11 +911,12 @@ static int get_codec_base_type(int type)
901 911
902static bool loadcodec(bool start_play) 912static bool loadcodec(bool start_play)
903{ 913{
904 off_t size; 914 size_t size;
905 int fd; 915 int fd;
906 int i, rc; 916 unsigned int i;
917 int rc;
907 const char *codec_path; 918 const char *codec_path;
908 int copy_n; 919 size_t copy_n;
909 int prev_track; 920 int prev_track;
910 921
911 switch (tracks[track_widx].id3.codectype) { 922 switch (tracks[track_widx].id3.codectype) {
@@ -994,7 +1005,7 @@ static bool loadcodec(bool start_play)
994 } 1005 }
995 1006
996 size = filesize(fd); 1007 size = filesize(fd);
997 if ((off_t)fill_bytesleft < size + conf_watermark) { 1008 if (fill_bytesleft < size + conf_watermark) {
998 logf("Not enough space"); 1009 logf("Not enough space");
999 /* Set codectype back to zero to indicate no codec was loaded. */ 1010 /* Set codectype back to zero to indicate no codec was loaded. */
1000 tracks[track_widx].id3.codectype = 0; 1011 tracks[track_widx].id3.codectype = 0;
@@ -1464,7 +1475,10 @@ static void audio_check_buffer(void)
1464 /* Limit buffering size at first run. */ 1475 /* Limit buffering size at first run. */
1465 if (conf_bufferlimit && fill_bytesleft > conf_bufferlimit 1476 if (conf_bufferlimit && fill_bytesleft > conf_bufferlimit
1466 - filebufused) { 1477 - filebufused) {
1467 fill_bytesleft = MAX(0, conf_bufferlimit - filebufused); 1478 if (conf_bufferlimit > filebufused)
1479 fill_bytesleft = conf_bufferlimit - filebufused;
1480 else
1481 fill_bytesleft = 0;
1468 } 1482 }
1469 1483
1470 /* Try to load remainings of the file. */ 1484 /* Try to load remainings of the file. */
@@ -1631,11 +1645,11 @@ static int skip_previous_track(bool inside_codec_thread)
1631 cur_ti->available = cur_ti->filesize - cur_ti->filerem; 1645 cur_ti->available = cur_ti->filesize - cur_ti->filerem;
1632 1646
1633 cur_ti = &tracks[track_ridx]; 1647 cur_ti = &tracks[track_ridx];
1634 buf_ridx -= cur_ti->filesize;
1635 filebufused += cur_ti->filesize; 1648 filebufused += cur_ti->filesize;
1636 cur_ti->available = cur_ti->filesize; 1649 cur_ti->available = cur_ti->filesize;
1637 if (buf_ridx < 0) 1650 if (buf_ridx < cur_ti->filesize)
1638 buf_ridx += filebuflen; 1651 buf_ridx += filebuflen;
1652 buf_ridx -= cur_ti->filesize;
1639 1653
1640 audio_update_trackinfo(); 1654 audio_update_trackinfo();
1641 1655
@@ -2096,8 +2110,6 @@ void voice_init(void)
2096 { 2110 {
2097 logf("Terminating voice codec"); 2111 logf("Terminating voice codec");
2098 ci_voice.stop_codec = true; 2112 ci_voice.stop_codec = true;
2099 if (current_codec != CODEC_IDX_VOICE)
2100 swap_codec();
2101 sleep(1); 2113 sleep(1);
2102 } 2114 }
2103 2115
diff --git a/apps/playback.h b/apps/playback.h
index 187ac0090e..250465274b 100644
--- a/apps/playback.h
+++ b/apps/playback.h
@@ -35,18 +35,18 @@
35 35
36#define MAX_TRACK 32 36#define MAX_TRACK 32
37struct track_info { 37struct track_info {
38 struct mp3entry id3; /* TAG metadata */ 38 struct mp3entry id3; /* TAG metadata */
39 char *codecbuf; /* Pointer to codec buffer */ 39 char *codecbuf; /* Pointer to codec buffer */
40 long codecsize; /* Codec length in bytes */ 40 size_t codecsize; /* Codec length in bytes */
41 41
42 off_t filerem; /* Remaining bytes of file NOT in buffer */ 42 size_t filerem; /* Remaining bytes of file NOT in buffer */
43 off_t filesize; /* File total length */ 43 size_t filesize; /* File total length */
44 off_t filepos; /* Read position of file for next buffer fill */ 44 size_t filepos; /* Read position of file for next buffer fill */
45 off_t start_pos; /* Position to first bytes of file in buffer */ 45 size_t start_pos; /* Position to first bytes of file in buffer */
46 volatile int available; /* Available bytes to read from buffer */ 46 volatile size_t available; /* Available bytes to read from buffer */
47 bool taginfo_ready; /* Is metadata read */ 47 bool taginfo_ready; /* Is metadata read */
48 int playlist_offset; /* File location in playlist */ 48 int playlist_offset; /* File location in playlist */
49 bool event_sent; /* Has event callback functions been called? */ 49 bool event_sent; /* Has event callback functions been called? */
50}; 50};
51 51
52/* Functions */ 52/* Functions */