summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/lang/english.lang6
-rw-r--r--apps/pcmbuf.c64
-rw-r--r--apps/playback.c379
-rw-r--r--apps/settings.c26
-rw-r--r--apps/settings_menu.c3
5 files changed, 243 insertions, 235 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index e591b46b9f..faaa637db0 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -3898,3 +3898,9 @@ desc: spoken only, for file extension
3898eng: "" 3898eng: ""
3899voice: "keyboard" 3899voice: "keyboard"
3900new: 3900new:
3901
3902id: LANG_TRACKSKIP
3903desc: in crossfade settings
3904eng: "Track Skip Only"
3905voice: "Track Skip Only"
3906new:
diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c
index 79a412c869..c0791987ce 100644
--- a/apps/pcmbuf.c
+++ b/apps/pcmbuf.c
@@ -116,10 +116,10 @@ static bool boost_mode;
116void pcmbuf_boost(bool state) 116void pcmbuf_boost(bool state)
117{ 117{
118 static bool boost_state = false; 118 static bool boost_state = false;
119 119
120 if (crossfade_init || crossfade_active || boost_mode) 120 if (crossfade_init || crossfade_active || boost_mode)
121 return; 121 return;
122 122
123 if (state != boost_state) { 123 if (state != boost_state) {
124 cpu_boost(state); 124 cpu_boost(state);
125 boost_state = state; 125 boost_state = state;
@@ -138,7 +138,7 @@ void pcmbuf_set_boost_mode(bool state)
138/* This function has 2 major logical parts (separated by brackets both for 138/* This function has 2 major logical parts (separated by brackets both for
139 * readability and variable scoping). The first part performs the 139 * readability and variable scoping). The first part performs the
140 * operastions related to finishing off the last buffer we fed to the DMA. 140 * operastions related to finishing off the last buffer we fed to the DMA.
141 * The second part performs the operations involved in sending a new buffer 141 * The second part performs the operations involved in sending a new buffer
142 * to the DMA. Finally the function checks the status of the buffer and 142 * to the DMA. Finally the function checks the status of the buffer and
143 * boosts if necessary */ 143 * boosts if necessary */
144static void pcmbuf_callback(unsigned char** start, size_t* size) ICODE_ATTR; 144static void pcmbuf_callback(unsigned char** start, size_t* size) ICODE_ATTR;
@@ -267,7 +267,7 @@ bool pcmbuf_is_lowdata(void)
267 if (!pcm_is_playing() || pcm_is_paused() || 267 if (!pcm_is_playing() || pcm_is_paused() ||
268 crossfade_init || crossfade_active) 268 crossfade_init || crossfade_active)
269 return false; 269 return false;
270 270
271 /* 0.5 seconds of buffer is low data */ 271 /* 0.5 seconds of buffer is low data */
272 return LOW_DATA(2); 272 return LOW_DATA(2);
273} 273}
@@ -290,9 +290,9 @@ bool pcmbuf_crossfade_init(bool manual_skip)
290 crossfade_mode = global_settings.crossfade_fade_out_mixmode 290 crossfade_mode = global_settings.crossfade_fade_out_mixmode
291 ? CFM_MIX : CFM_CROSSFADE; 291 ? CFM_MIX : CFM_CROSSFADE;
292 crossfade_init = true; 292 crossfade_init = true;
293 293
294 return true; 294 return true;
295 295
296} 296}
297 297
298void pcmbuf_play_stop(void) 298void pcmbuf_play_stop(void)
@@ -303,7 +303,7 @@ void pcmbuf_play_stop(void)
303 pcm_mute(true); 303 pcm_mute(true);
304 pcm_play_stop(); 304 pcm_play_stop();
305 pcm_mute(false); 305 pcm_mute(false);
306 306
307 pcmbuf_unplayed_bytes = 0; 307 pcmbuf_unplayed_bytes = 0;
308 pcmbuf_mix_used_bytes = 0; 308 pcmbuf_mix_used_bytes = 0;
309 if (pcmbuf_read) { 309 if (pcmbuf_read) {
@@ -316,7 +316,7 @@ void pcmbuf_play_stop(void)
316 audiobuffer_free = pcmbuf_size; 316 audiobuffer_free = pcmbuf_size;
317 crossfade_init = false; 317 crossfade_init = false;
318 crossfade_active = false; 318 crossfade_active = false;
319 319
320 pcmbuf_set_boost_mode(false); 320 pcmbuf_set_boost_mode(false);
321 pcmbuf_boost(false); 321 pcmbuf_boost(false);
322 322
@@ -340,7 +340,7 @@ int pcmbuf_descs(void) {
340size_t get_pcmbuf_descsize(void) { 340size_t get_pcmbuf_descsize(void) {
341 return pcmbuf_descsize; 341 return pcmbuf_descsize;
342} 342}
343 343
344static void pcmbuf_init_pcmbuffers(void) { 344static void pcmbuf_init_pcmbuffers(void) {
345 struct pcmbufdesc *next = pcmbuf_write; 345 struct pcmbufdesc *next = pcmbuf_write;
346 next++; 346 next++;
@@ -351,7 +351,7 @@ static void pcmbuf_init_pcmbuffers(void) {
351 next++; 351 next++;
352 } 352 }
353} 353}
354 354
355/* Initialize the pcmbuffer the structure looks like this: 355/* Initialize the pcmbuffer the structure looks like this:
356 * ...CODECBUFFER|---------PCMBUF---------|GUARDBUF|DESCS| */ 356 * ...CODECBUFFER|---------PCMBUF---------|GUARDBUF|DESCS| */
357void pcmbuf_init(size_t bufsize) 357void pcmbuf_init(size_t bufsize)
@@ -383,7 +383,7 @@ static void pcmbuf_flush_audio(void)
383 pcmbuf_play_stop(); 383 pcmbuf_play_stop();
384 return ; 384 return ;
385 } 385 }
386 386
387 pcmbuf_boost(true); 387 pcmbuf_boost(true);
388 crossfade_mode = CFM_FLUSH; 388 crossfade_mode = CFM_FLUSH;
389 crossfade_init = true; 389 crossfade_init = true;
@@ -408,10 +408,10 @@ void pcmbuf_play_start(void)
408 /** Prevent a very tiny pop from happening by muting audio 408 /** Prevent a very tiny pop from happening by muting audio
409 * until dma has been initialized. */ 409 * until dma has been initialized. */
410 pcm_mute(true); 410 pcm_mute(true);
411 411
412 last_chunksize = pcmbuf_read->size; 412 last_chunksize = pcmbuf_read->size;
413 pcmbuf_unplayed_bytes -= last_chunksize; 413 pcmbuf_unplayed_bytes -= last_chunksize;
414 pcm_play_data(pcmbuf_callback, 414 pcm_play_data(pcmbuf_callback,
415 (unsigned char *)pcmbuf_read->addr, last_chunksize); 415 (unsigned char *)pcmbuf_read->addr, last_chunksize);
416 416
417 /* Now unmute the audio. */ 417 /* Now unmute the audio. */
@@ -470,7 +470,7 @@ static void crossfade_process_buffer(size_t fade_in_delay,
470 size_t block_rem = MIN(NATIVE_FREQUENCY * 2 / 10, fade_out_rem); 470 size_t block_rem = MIN(NATIVE_FREQUENCY * 2 / 10, fade_out_rem);
471 unsigned int factor = (fade_out_rem << 8) / total_fade_out; 471 unsigned int factor = (fade_out_rem << 8) / total_fade_out;
472 short *block_end = buf + block_rem; 472 short *block_end = buf + block_rem;
473 473
474 fade_out_rem -= block_rem; 474 fade_out_rem -= block_rem;
475 475
476 /* Fade this block */ 476 /* Fade this block */
@@ -508,7 +508,7 @@ static void crossfade_start(void)
508 size_t fade_out_rem = 0; 508 size_t fade_out_rem = 0;
509 unsigned int fade_out_delay = 0; 509 unsigned int fade_out_delay = 0;
510 unsigned fade_in_delay = 0; 510 unsigned fade_in_delay = 0;
511 511
512 crossfade_init = 0; 512 crossfade_init = 0;
513 /* Reject crossfade if less than .5s of data */ 513 /* Reject crossfade if less than .5s of data */
514 if (LOW_DATA(2)) { 514 if (LOW_DATA(2)) {
@@ -556,7 +556,7 @@ static void crossfade_start(void)
556 556
557 fade_in_delay = NATIVE_FREQUENCY 557 fade_in_delay = NATIVE_FREQUENCY
558 * global_settings.crossfade_fade_in_delay * 2; 558 * global_settings.crossfade_fade_in_delay * 2;
559 559
560 /* Decrease the fade out delay if necessary. */ 560 /* Decrease the fade out delay if necessary. */
561 if (crossfade_rem < fade_out_rem + fade_out_delay) 561 if (crossfade_rem < fade_out_rem + fade_out_delay)
562 fade_out_delay -= 562 fade_out_delay -=
@@ -568,16 +568,16 @@ static void crossfade_start(void)
568 crossfade_fade_in_amount = 0; 568 crossfade_fade_in_amount = 0;
569 break ; 569 break ;
570 } 570 }
571 571
572 if (crossfade_pos < crossfade_rem * 2) 572 if (crossfade_pos < crossfade_rem * 2)
573 crossfade_pos += pcmbuf_size; 573 crossfade_pos += pcmbuf_size;
574 crossfade_pos -= crossfade_rem*2; 574 crossfade_pos -= crossfade_rem*2;
575 575
576 if (crossfade_mode != CFM_FLUSH) { 576 if (crossfade_mode != CFM_FLUSH) {
577 /* Process the fade out part of the crossfade. */ 577 /* Process the fade out part of the crossfade. */
578 crossfade_process_buffer(fade_in_delay, fade_out_delay, fade_out_rem); 578 crossfade_process_buffer(fade_in_delay, fade_out_delay, fade_out_rem);
579 } 579 }
580 580
581} 581}
582 582
583/** 583/**
@@ -590,7 +590,7 @@ static void fade_insert(const short *inbuf, size_t length)
590 int factor; 590 int factor;
591 unsigned int i, samples; 591 unsigned int i, samples;
592 short *buf; 592 short *buf;
593 593
594 factor = ((crossfade_fade_in_amount-crossfade_fade_in_rem)<<8) 594 factor = ((crossfade_fade_in_amount-crossfade_fade_in_rem)<<8)
595 /crossfade_fade_in_amount; 595 /crossfade_fade_in_amount;
596 596
@@ -600,7 +600,7 @@ static void fade_insert(const short *inbuf, size_t length)
600 sleep(1); 600 sleep(1);
601 } 601 }
602 audiobuffer_free -= length; 602 audiobuffer_free -= length;
603 603
604 while (length > 0) { 604 while (length > 0) {
605 unsigned int audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos; 605 unsigned int audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos;
606 /* Flush as needed */ 606 /* Flush as needed */
@@ -609,14 +609,14 @@ static void fade_insert(const short *inbuf, size_t length)
609 pcmbuf_flush_fillpos(); 609 pcmbuf_flush_fillpos();
610 audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos; 610 audiobuffer_index = audiobuffer_pos + audiobuffer_fillpos;
611 } 611 }
612 612
613 copy_n = MIN(length, pcmbuf_size - audiobuffer_index); 613 copy_n = MIN(length, pcmbuf_size - audiobuffer_index);
614 614
615 buf = (short *)&audiobuffer[audiobuffer_index]; 615 buf = (short *)&audiobuffer[audiobuffer_index];
616 samples = copy_n / 2; 616 samples = copy_n / 2;
617 for (i = 0; i < samples; i++) 617 for (i = 0; i < samples; i++)
618 buf[i] = (inbuf[i] * factor) >> 8; 618 buf[i] = (inbuf[i] * factor) >> 8;
619 619
620 inbuf += samples; 620 inbuf += samples;
621 audiobuffer_fillpos += copy_n; 621 audiobuffer_fillpos += copy_n;
622 length -= copy_n; 622 length -= copy_n;
@@ -632,7 +632,7 @@ static int crossfade(short *buf, const short *buf2, unsigned int length)
632 unsigned int i; 632 unsigned int i;
633 size_t size_insert = 0; 633 size_t size_insert = 0;
634 int factor; 634 int factor;
635 635
636 size = MIN(length, crossfade_rem); 636 size = MIN(length, crossfade_rem);
637 switch (crossfade_mode) { 637 switch (crossfade_mode) {
638 /* Fade in the current stream and mix it. */ 638 /* Fade in the current stream and mix it. */
@@ -640,9 +640,9 @@ static int crossfade(short *buf, const short *buf2, unsigned int length)
640 case CFM_CROSSFADE: 640 case CFM_CROSSFADE:
641 factor = ((crossfade_fade_in_amount-crossfade_fade_in_rem)<<8) / 641 factor = ((crossfade_fade_in_amount-crossfade_fade_in_rem)<<8) /
642 crossfade_fade_in_amount; 642 crossfade_fade_in_amount;
643 643
644 for (i = 0; i < size; i++) { 644 for (i = 0; i < size; i++) {
645 buf[i] = MIN(32767, MAX(-32768, 645 buf[i] = MIN(32767, MAX(-32768,
646 buf[i] + ((buf2[i] * factor) >> 8))); 646 buf[i] + ((buf2[i] * factor) >> 8)));
647 } 647 }
648 break ; 648 break ;
@@ -670,7 +670,7 @@ static int crossfade(short *buf, const short *buf2, unsigned int length)
670 fade_insert(&buf2[size], size_insert*2); 670 fade_insert(&buf2[size], size_insert*2);
671 crossfade_fade_in_rem -= size_insert; 671 crossfade_fade_in_rem -= size_insert;
672 } 672 }
673 673
674 if (crossfade_fade_in_rem == 0) 674 if (crossfade_fade_in_rem == 0)
675 crossfade_active = false; 675 crossfade_active = false;
676 } 676 }
@@ -726,7 +726,7 @@ static bool prepare_insert(size_t length)
726 && pcm_is_playing()) 726 && pcm_is_playing())
727 return false; 727 return false;
728 } 728 }
729 729
730 /* Need to save PCMBUF_MIN_CHUNK to prevent wrapping overwriting */ 730 /* Need to save PCMBUF_MIN_CHUNK to prevent wrapping overwriting */
731 if (audiobuffer_free < length + PCMBUF_MIN_CHUNK && !crossfade_active) 731 if (audiobuffer_free < length + PCMBUF_MIN_CHUNK && !crossfade_active)
732 { 732 {
@@ -835,7 +835,7 @@ static inline short* get_mix_insert_pos(void) {
835 /* Give at least 1/8s clearance here */ 835 /* Give at least 1/8s clearance here */
836 size_t pcmbuf_mix_back_pos = 836 size_t pcmbuf_mix_back_pos =
837 pcmbuf_unplayed_bytes - NATIVE_FREQUENCY * 4 / 8; 837 pcmbuf_unplayed_bytes - NATIVE_FREQUENCY * 4 / 8;
838 838
839 if (audiobuffer_pos < pcmbuf_mix_back_pos) 839 if (audiobuffer_pos < pcmbuf_mix_back_pos)
840 return (short *)&audiobuffer[pcmbuf_size + 840 return (short *)&audiobuffer[pcmbuf_size +
841 audiobuffer_pos - pcmbuf_mix_back_pos]; 841 audiobuffer_pos - pcmbuf_mix_back_pos];
@@ -854,7 +854,7 @@ void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
854 short *pcmbuf_end = (short *)guardbuf; 854 short *pcmbuf_end = (short *)guardbuf;
855 bool playing = pcm_is_playing(); 855 bool playing = pcm_is_playing();
856 size_t samples = NATIVE_FREQUENCY / 1000 * duration; 856 size_t samples = NATIVE_FREQUENCY / 1000 * duration;
857 857
858 if (playing) { 858 if (playing) {
859 buf = get_mix_insert_pos(); 859 buf = get_mix_insert_pos();
860 } else { 860 } else {
@@ -876,7 +876,7 @@ void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
876 sample = *buf; 876 sample = *buf;
877 *buf++ = MIN(MAX(sample - amplitude, -32768), 32767); 877 *buf++ = MIN(MAX(sample - amplitude, -32768), 32767);
878 } 878 }
879 879
880 if (++count >= interval) 880 if (++count >= interval)
881 { 881 {
882 count = 0; 882 count = 0;
@@ -914,7 +914,7 @@ void pcmbuf_mix(char *buf, size_t length)
914 914
915 if (pcmbuf_mix_used_bytes == 0) 915 if (pcmbuf_mix_used_bytes == 0)
916 pcmbuf_reset_mixpos(); 916 pcmbuf_reset_mixpos();
917 917
918 pcmbuf_mix_used_bytes += length; 918 pcmbuf_mix_used_bytes += length;
919 length /= 2; 919 length /= 2;
920 920
diff --git a/apps/playback.c b/apps/playback.c
index 80811c2d81..7b20beba23 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -104,7 +104,7 @@ enum {
104 Q_AUDIO_DIR_PREV, 104 Q_AUDIO_DIR_PREV,
105 Q_AUDIO_SEAMLESS_SEEK, 105 Q_AUDIO_SEAMLESS_SEEK,
106 Q_AUDIO_POSTINIT, 106 Q_AUDIO_POSTINIT,
107 107
108 Q_CODEC_LOAD, 108 Q_CODEC_LOAD,
109 Q_CODEC_LOAD_DISK, 109 Q_CODEC_LOAD_DISK,
110}; 110};
@@ -272,7 +272,7 @@ static void voice_boost_cpu(bool state)
272 272
273 if (!voice_codec_loaded) 273 if (!voice_codec_loaded)
274 state = false; 274 state = false;
275 275
276 if (state != voice_cpu_boosted) 276 if (state != voice_cpu_boosted)
277 { 277 {
278 cpu_boost(state); 278 cpu_boost(state);
@@ -309,7 +309,7 @@ bool codec_pcmbuf_insert_split_callback(const void *ch1, const void *ch2,
309 } 309 }
310 else 310 else
311 { 311 {
312 if (ci.reload_codec || ci.stop_codec) 312 if (ci.reload_codec || ci.stop_codec)
313 return true; 313 return true;
314 314
315 while ((dest = pcmbuf_request_buffer(est_output_size, 315 while ((dest = pcmbuf_request_buffer(est_output_size,
@@ -323,7 +323,7 @@ bool codec_pcmbuf_insert_split_callback(const void *ch1, const void *ch2,
323 /* Get the real input_size for output_size bytes, guarding 323 /* Get the real input_size for output_size bytes, guarding
324 * against resampling buffer overflows. */ 324 * against resampling buffer overflows. */
325 input_size = dsp_input_size(output_size); 325 input_size = dsp_input_size(output_size);
326 326
327 if (input_size <= 0) { 327 if (input_size <= 0) {
328 DEBUGF("Warning: dsp_input_size(%ld=dsp_output_size(%ld))=%ld <= 0\n", 328 DEBUGF("Warning: dsp_input_size(%ld=dsp_output_size(%ld))=%ld <= 0\n",
329 output_size, length, input_size); 329 output_size, length, input_size);
@@ -336,7 +336,7 @@ bool codec_pcmbuf_insert_split_callback(const void *ch1, const void *ch2,
336 output_size, length, input_size, length); 336 output_size, length, input_size, length);
337 input_size = length; 337 input_size = length;
338 } 338 }
339 339
340 output_size = dsp_process(dest, src, input_size); 340 output_size = dsp_process(dest, src, input_size);
341 341
342 /* Hotswap between audio and voice codecs as necessary. */ 342 /* Hotswap between audio and voice codecs as necessary. */
@@ -364,7 +364,7 @@ bool codec_pcmbuf_insert_split_callback(const void *ch1, const void *ch2,
364 } 364 }
365 break ; 365 break ;
366 } 366 }
367 367
368 length -= input_size; 368 length -= input_size;
369 } 369 }
370 370
@@ -416,15 +416,15 @@ void codec_set_elapsed_callback(unsigned int value)
416 /* We don't save or display offsets for voice */ 416 /* We don't save or display offsets for voice */
417 if (current_codec == CODEC_IDX_VOICE) 417 if (current_codec == CODEC_IDX_VOICE)
418 return ; 418 return ;
419 419
420#ifdef AB_REPEAT_ENABLE 420#ifdef AB_REPEAT_ENABLE
421 ab_position_report(value); 421 ab_position_report(value);
422#endif 422#endif
423 latency = pcmbuf_get_latency(); 423 latency = pcmbuf_get_latency();
424 424
425 if (value < latency) { 425 if (value < latency) {
426 cur_ti->id3.elapsed = 0; 426 cur_ti->id3.elapsed = 0;
427 } else if (value - latency > cur_ti->id3.elapsed 427 } else if (value - latency > cur_ti->id3.elapsed
428 || value - latency < cur_ti->id3.elapsed - 2) { 428 || value - latency < cur_ti->id3.elapsed - 2) {
429 cur_ti->id3.elapsed = value - latency; 429 cur_ti->id3.elapsed = value - latency;
430 } 430 }
@@ -437,9 +437,9 @@ void codec_set_offset_callback(size_t value)
437 /* We don't save or display offsets for voice */ 437 /* We don't save or display offsets for voice */
438 if (current_codec == CODEC_IDX_VOICE) 438 if (current_codec == CODEC_IDX_VOICE)
439 return ; 439 return ;
440 440
441 latency = pcmbuf_get_latency() * cur_ti->id3.bitrate / 8; 441 latency = pcmbuf_get_latency() * cur_ti->id3.bitrate / 8;
442 442
443 if (value < latency) { 443 if (value < latency) {
444 cur_ti->id3.offset = 0; 444 cur_ti->id3.offset = 0;
445 } else { 445 } else {
@@ -462,25 +462,25 @@ size_t codec_filebuf_callback(void *ptr, size_t size)
462 char *buf = (char *)ptr; 462 char *buf = (char *)ptr;
463 size_t copy_n; 463 size_t copy_n;
464 size_t part_n; 464 size_t part_n;
465 465
466 if (ci.stop_codec || !playing || current_codec == CODEC_IDX_VOICE) 466 if (ci.stop_codec || !playing || current_codec == CODEC_IDX_VOICE)
467 return 0; 467 return 0;
468 468
469 /* The ammount to copy is the lesser of the requested amount and the 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) */ 470 * amount left of the current track (both on disk and already loaded) */
471 copy_n = MIN(size, cur_ti->available + cur_ti->filerem); 471 copy_n = MIN(size, cur_ti->available + cur_ti->filerem);
472 472
473 /* Nothing requested OR nothing left */ 473 /* Nothing requested OR nothing left */
474 if (copy_n == 0) 474 if (copy_n == 0)
475 return 0; 475 return 0;
476 476
477 /* Let the disk buffer catch fill until enough data is available */ 477 /* Let the disk buffer catch fill until enough data is available */
478 while (copy_n > cur_ti->available) { 478 while (copy_n > cur_ti->available) {
479 yield(); 479 yield();
480 if (ci.stop_codec || ci.reload_codec) 480 if (ci.stop_codec || ci.reload_codec)
481 return 0; 481 return 0;
482 } 482 }
483 483
484 /* Copy as much as possible without wrapping */ 484 /* Copy as much as possible without wrapping */
485 part_n = MIN(copy_n, filebuflen - buf_ridx); 485 part_n = MIN(copy_n, filebuflen - buf_ridx);
486 memcpy(buf, &filebuf[buf_ridx], part_n); 486 memcpy(buf, &filebuf[buf_ridx], part_n);
@@ -488,10 +488,10 @@ size_t codec_filebuf_callback(void *ptr, size_t size)
488 if (part_n < copy_n) { 488 if (part_n < copy_n) {
489 memcpy(&buf[part_n], &filebuf[0], copy_n - part_n); 489 memcpy(&buf[part_n], &filebuf[0], copy_n - part_n);
490 } 490 }
491 491
492 /* Update read and other position pointers */ 492 /* Update read and other position pointers */
493 advance_buffer_counters(copy_n); 493 advance_buffer_counters(copy_n);
494 494
495 /* Return the actual amount of data copied to the buffer */ 495 /* Return the actual amount of data copied to the buffer */
496 return copy_n; 496 return copy_n;
497} 497}
@@ -514,7 +514,7 @@ void* voice_request_data(size_t *realsize, size_t reqsize)
514 pcmbuf_boost(false); 514 pcmbuf_boost(false);
515 sleep(HZ/16); 515 sleep(HZ/16);
516 } 516 }
517 517
518 if (voice_remaining) 518 if (voice_remaining)
519 { 519 {
520 voice_is_playing = true; 520 voice_is_playing = true;
@@ -549,18 +549,18 @@ void* codec_request_buffer_callback(size_t *realsize, size_t reqsize)
549 if (current_codec == CODEC_IDX_VOICE) { 549 if (current_codec == CODEC_IDX_VOICE) {
550 return voice_request_data(realsize, reqsize); 550 return voice_request_data(realsize, reqsize);
551 } 551 }
552 552
553 if (ci.stop_codec || !playing) { 553 if (ci.stop_codec || !playing) {
554 *realsize = 0; 554 *realsize = 0;
555 return NULL; 555 return NULL;
556 } 556 }
557 557
558 copy_n = MIN(reqsize, cur_ti->available + cur_ti->filerem); 558 copy_n = MIN(reqsize, cur_ti->available + cur_ti->filerem);
559 if (copy_n == 0) { 559 if (copy_n == 0) {
560 *realsize = 0; 560 *realsize = 0;
561 return NULL; 561 return NULL;
562 } 562 }
563 563
564 while (copy_n > cur_ti->available) { 564 while (copy_n > cur_ti->available) {
565 yield(); 565 yield();
566 if (ci.stop_codec || ci.reload_codec) { 566 if (ci.stop_codec || ci.reload_codec) {
@@ -568,7 +568,7 @@ void* codec_request_buffer_callback(size_t *realsize, size_t reqsize)
568 return NULL; 568 return NULL;
569 } 569 }
570 } 570 }
571 571
572 /* How much is left at the end of the file buffer before wrap? */ 572 /* How much is left at the end of the file buffer before wrap? */
573 buf_rem = filebuflen - buf_ridx; 573 buf_rem = filebuflen - buf_ridx;
574 /* If we can't satisfy the request without wrapping */ 574 /* If we can't satisfy the request without wrapping */
@@ -581,7 +581,7 @@ void* codec_request_buffer_callback(size_t *realsize, size_t reqsize)
581 else 581 else
582 copy_n = buf_rem; 582 copy_n = buf_rem;
583 } 583 }
584 584
585 *realsize = copy_n; 585 *realsize = copy_n;
586 return (char *)&filebuf[buf_ridx]; 586 return (char *)&filebuf[buf_ridx];
587} 587}
@@ -603,7 +603,7 @@ static bool rebuffer_and_seek(size_t newpos)
603 if (current_fd >= 0) 603 if (current_fd >= 0)
604 close(current_fd); 604 close(current_fd);
605 current_fd = fd; 605 current_fd = fd;
606 606
607 /* Clear codec buffer. */ 607 /* Clear codec buffer. */
608 audio_invalidate_tracks(); 608 audio_invalidate_tracks();
609 filebufused = 0; 609 filebufused = 0;
@@ -623,7 +623,7 @@ static bool rebuffer_and_seek(size_t newpos)
623 if (ci.stop_codec || ci.reload_codec || !queue_empty(&audio_queue)) 623 if (ci.stop_codec || ci.reload_codec || !queue_empty(&audio_queue))
624 return false; 624 return false;
625 } 625 }
626 626
627 return true; 627 return true;
628} 628}
629 629
@@ -634,22 +634,22 @@ void codec_advance_buffer_callback(size_t amount)
634 amount = MIN(amount, voice_remaining); 634 amount = MIN(amount, voice_remaining);
635 voicebuf += amount; 635 voicebuf += amount;
636 voice_remaining -= amount; 636 voice_remaining -= amount;
637 637
638 return ; 638 return ;
639 } 639 }
640 640
641 if (amount > cur_ti->available + cur_ti->filerem) 641 if (amount > cur_ti->available + cur_ti->filerem)
642 amount = cur_ti->available + cur_ti->filerem; 642 amount = cur_ti->available + cur_ti->filerem;
643 643
644 while (amount > cur_ti->available && filling) 644 while (amount > cur_ti->available && filling)
645 sleep(1); 645 sleep(1);
646 646
647 if (amount > cur_ti->available) { 647 if (amount > cur_ti->available) {
648 if (!rebuffer_and_seek(ci.curpos + amount)) 648 if (!rebuffer_and_seek(ci.curpos + amount))
649 ci.stop_codec = true; 649 ci.stop_codec = true;
650 return ; 650 return ;
651 } 651 }
652 652
653 advance_buffer_counters(amount); 653 advance_buffer_counters(amount);
654 654
655 codec_set_offset_callback(ci.curpos); 655 codec_set_offset_callback(ci.curpos);
@@ -672,7 +672,7 @@ off_t codec_mp3_get_filepos_callback(int newtime)
672 672
673 cur_ti->id3.elapsed = newtime; 673 cur_ti->id3.elapsed = newtime;
674 newpos = mp3_get_file_pos(); 674 newpos = mp3_get_file_pos();
675 675
676 return newpos; 676 return newpos;
677} 677}
678 678
@@ -688,10 +688,10 @@ bool codec_seek_buffer_callback(size_t newpos)
688 688
689 if (current_codec == CODEC_IDX_VOICE) 689 if (current_codec == CODEC_IDX_VOICE)
690 return false; 690 return false;
691 691
692 if (newpos >= cur_ti->filesize) 692 if (newpos >= cur_ti->filesize)
693 newpos = cur_ti->filesize - 1; 693 newpos = cur_ti->filesize - 1;
694 694
695 difference = newpos - ci.curpos; 695 difference = newpos - ci.curpos;
696 /* Seeking forward */ 696 /* Seeking forward */
697 if (difference >= 0) { 697 if (difference >= 0) {
@@ -704,7 +704,7 @@ bool codec_seek_buffer_callback(size_t newpos)
704 difference = -difference; 704 difference = -difference;
705 if (ci.curpos - difference < 0) 705 if (ci.curpos - difference < 0)
706 difference = ci.curpos; 706 difference = ci.curpos;
707 707
708 /* We need to reload the song. */ 708 /* We need to reload the song. */
709 if (newpos < cur_ti->start_pos) 709 if (newpos < cur_ti->start_pos)
710 return rebuffer_and_seek(newpos); 710 return rebuffer_and_seek(newpos);
@@ -717,7 +717,7 @@ bool codec_seek_buffer_callback(size_t newpos)
717 buf_ridx += filebuflen; 717 buf_ridx += filebuflen;
718 buf_ridx -= difference; 718 buf_ridx -= difference;
719 ci.curpos -= difference; 719 ci.curpos -= difference;
720 720
721 return true; 721 return true;
722} 722}
723 723
@@ -730,7 +730,7 @@ static void set_filebuf_watermark(int seconds)
730 730
731 if (!filebuf) 731 if (!filebuf)
732 return; /* Audio buffers not yet set up */ 732 return; /* Audio buffers not yet set up */
733 733
734 bytes = MAX(cur_ti->id3.bitrate * seconds * (1000/8), conf_watermark); 734 bytes = MAX(cur_ti->id3.bitrate * seconds * (1000/8), conf_watermark);
735 bytes = MIN(bytes, filebuflen / 2); 735 bytes = MIN(bytes, filebuflen / 2);
736 conf_watermark = bytes; 736 conf_watermark = bytes;
@@ -743,11 +743,11 @@ static void codec_configure_callback(int setting, void *value)
743 conf_watermark = (unsigned long)value; 743 conf_watermark = (unsigned long)value;
744 set_filebuf_watermark(buffer_margin); 744 set_filebuf_watermark(buffer_margin);
745 break; 745 break;
746 746
747 case CODEC_SET_FILEBUF_CHUNKSIZE: 747 case CODEC_SET_FILEBUF_CHUNKSIZE:
748 conf_filechunk = (unsigned long)value; 748 conf_filechunk = (unsigned long)value;
749 break; 749 break;
750 750
751 case CODEC_DSP_ENABLE: 751 case CODEC_DSP_ENABLE:
752 if ((bool)value) 752 if ((bool)value)
753 ci.pcmbuf_insert = codec_pcmbuf_insert_callback; 753 ci.pcmbuf_insert = codec_pcmbuf_insert_callback;
@@ -819,21 +819,21 @@ void strip_id3v1_tag(void)
819 tagptr = filebuflen + buf_widx - 128; 819 tagptr = filebuflen + buf_widx - 128;
820 else 820 else
821 tagptr = buf_widx - 128; 821 tagptr = buf_widx - 128;
822 822
823 for(i = 0;i < 3;i++) 823 for(i = 0;i < 3;i++)
824 { 824 {
825 if(tagptr >= filebuflen) 825 if(tagptr >= filebuflen)
826 tagptr -= filebuflen; 826 tagptr -= filebuflen;
827 827
828 if(filebuf[tagptr] != tag[i]) 828 if(filebuf[tagptr] != tag[i])
829 { 829 {
830 found = false; 830 found = false;
831 break; 831 break;
832 } 832 }
833 833
834 tagptr++; 834 tagptr++;
835 } 835 }
836 836
837 if(found) 837 if(found)
838 { 838 {
839 /* Skip id3v1 tag */ 839 /* Skip id3v1 tag */
@@ -858,14 +858,14 @@ static void audio_fill_file_buffer(void)
858 /* Throw away buffered codec. */ 858 /* Throw away buffered codec. */
859 if (tracks[track_widx].start_pos != 0) 859 if (tracks[track_widx].start_pos != 0)
860 tracks[track_widx].codecsize = 0; 860 tracks[track_widx].codecsize = 0;
861 861
862 mutex_lock(&mutex_bufferfill); 862 mutex_lock(&mutex_bufferfill);
863 i = 0; 863 i = 0;
864 size = MIN(tracks[track_widx].filerem, AUDIO_FILL_CYCLE); 864 size = MIN(tracks[track_widx].filerem, AUDIO_FILL_CYCLE);
865 while (i < size) { 865 while (i < size) {
866 /* Give codecs some processing time. */ 866 /* Give codecs some processing time. */
867 yield_codecs(); 867 yield_codecs();
868 868
869 if (fill_bytesleft == 0) 869 if (fill_bytesleft == 0)
870 break ; 870 break ;
871 copy_n = MIN(conf_filechunk, filebuflen - buf_widx); 871 copy_n = MIN(conf_filechunk, filebuflen - buf_widx);
@@ -875,7 +875,7 @@ static void audio_fill_file_buffer(void)
875 tracks[track_widx].filerem = 0; 875 tracks[track_widx].filerem = 0;
876 break ; 876 break ;
877 } 877 }
878 878
879 buf_widx += rc; 879 buf_widx += rc;
880 if (buf_widx >= filebuflen) 880 if (buf_widx >= filebuflen)
881 buf_widx -= filebuflen; 881 buf_widx -= filebuflen;
@@ -892,7 +892,7 @@ static void audio_fill_file_buffer(void)
892 } 892 }
893 893
894 mutex_unlock(&mutex_bufferfill); 894 mutex_unlock(&mutex_bufferfill);
895 895
896 /*logf("Filled:%d/%d", tracks[track_widx].available, 896 /*logf("Filled:%d/%d", tracks[track_widx].available,
897 tracks[track_widx].filerem);*/ 897 tracks[track_widx].filerem);*/
898} 898}
@@ -918,7 +918,7 @@ static bool loadcodec(bool start_play)
918 const char *codec_path; 918 const char *codec_path;
919 size_t copy_n; 919 size_t copy_n;
920 int prev_track; 920 int prev_track;
921 921
922 switch (tracks[track_widx].id3.codectype) { 922 switch (tracks[track_widx].id3.codectype) {
923 case AFMT_OGG_VORBIS: 923 case AFMT_OGG_VORBIS:
924 logf("Codec: Vorbis"); 924 logf("Codec: Vorbis");
@@ -971,14 +971,14 @@ static bool loadcodec(bool start_play)
971 codec_path = NULL; 971 codec_path = NULL;
972 return false; 972 return false;
973 } 973 }
974 974
975 tracks[track_widx].codecsize = 0; 975 tracks[track_widx].codecsize = 0;
976 976
977 if (!start_play) { 977 if (!start_play) {
978 prev_track = track_widx - 1; 978 prev_track = track_widx - 1;
979 if (prev_track < 0) 979 if (prev_track < 0)
980 prev_track = MAX_TRACK-1; 980 prev_track = MAX_TRACK-1;
981 if (track_count > 0 && 981 if (track_count > 0 &&
982 get_codec_base_type(tracks[track_widx].id3.codectype) == 982 get_codec_base_type(tracks[track_widx].id3.codectype) ==
983 get_codec_base_type(tracks[prev_track].id3.codectype)) 983 get_codec_base_type(tracks[prev_track].id3.codectype))
984 { 984 {
@@ -997,13 +997,13 @@ static bool loadcodec(bool start_play)
997 queue_post(&codec_queue, Q_CODEC_LOAD_DISK, (void *)codec_path); 997 queue_post(&codec_queue, Q_CODEC_LOAD_DISK, (void *)codec_path);
998 return true; 998 return true;
999 } 999 }
1000 1000
1001 fd = open(codec_path, O_RDONLY); 1001 fd = open(codec_path, O_RDONLY);
1002 if (fd < 0) { 1002 if (fd < 0) {
1003 logf("Codec doesn't exist!"); 1003 logf("Codec doesn't exist!");
1004 return false; 1004 return false;
1005 } 1005 }
1006 1006
1007 size = filesize(fd); 1007 size = filesize(fd);
1008 if (fill_bytesleft < size + conf_watermark) { 1008 if (fill_bytesleft < size + conf_watermark) {
1009 logf("Not enough space"); 1009 logf("Not enough space");
@@ -1013,11 +1013,11 @@ static bool loadcodec(bool start_play)
1013 close(fd); 1013 close(fd);
1014 return false; 1014 return false;
1015 } 1015 }
1016 1016
1017 i = 0; 1017 i = 0;
1018 while (i < size) { 1018 while (i < size) {
1019 yield_codecs(); 1019 yield_codecs();
1020 1020
1021 copy_n = MIN(conf_filechunk, filebuflen - buf_widx); 1021 copy_n = MIN(conf_filechunk, filebuflen - buf_widx);
1022 rc = read(fd, &filebuf[buf_widx], copy_n); 1022 rc = read(fd, &filebuf[buf_widx], copy_n);
1023 if (rc < 0) 1023 if (rc < 0)
@@ -1031,9 +1031,9 @@ static bool loadcodec(bool start_play)
1031 } 1031 }
1032 close(fd); 1032 close(fd);
1033 logf("Done: %dB", i); 1033 logf("Done: %dB", i);
1034 1034
1035 tracks[track_widx].codecsize = size; 1035 tracks[track_widx].codecsize = size;
1036 1036
1037 return true; 1037 return true;
1038} 1038}
1039 1039
@@ -1047,13 +1047,13 @@ static bool read_next_metadata(void)
1047 next_track = track_widx; 1047 next_track = track_widx;
1048 if (tracks[track_widx].taginfo_ready) 1048 if (tracks[track_widx].taginfo_ready)
1049 next_track++; 1049 next_track++;
1050 1050
1051 if (next_track >= MAX_TRACK) 1051 if (next_track >= MAX_TRACK)
1052 next_track -= MAX_TRACK; 1052 next_track -= MAX_TRACK;
1053 1053
1054 if (tracks[next_track].taginfo_ready) 1054 if (tracks[next_track].taginfo_ready)
1055 return true; 1055 return true;
1056 1056
1057 trackname = playlist_peek(last_peek_offset + 1); 1057 trackname = playlist_peek(last_peek_offset + 1);
1058 if (!trackname) 1058 if (!trackname)
1059 return false; 1059 return false;
@@ -1061,7 +1061,7 @@ static bool read_next_metadata(void)
1061 fd = open(trackname, O_RDONLY); 1061 fd = open(trackname, O_RDONLY);
1062 if (fd < 0) 1062 if (fd < 0)
1063 return false; 1063 return false;
1064 1064
1065 /** Start buffer refilling also because we need to spin-up the disk. 1065 /** Start buffer refilling also because we need to spin-up the disk.
1066 * In fact, it might be better not to start filling here, because if user 1066 * In fact, it might be better not to start filling here, because if user
1067 * is manipulating the playlist a lot, we will just lose battery. */ 1067 * is manipulating the playlist a lot, we will just lose battery. */
@@ -1119,13 +1119,13 @@ static bool audio_load_track(int offset, bool start_play, int peek_offset)
1119 } 1119 }
1120 break ; 1120 break ;
1121 } 1121 }
1122 1122
1123 if (!trackname) { 1123 if (!trackname) {
1124 logf("End-of-playlist"); 1124 logf("End-of-playlist");
1125 playlist_end = true; 1125 playlist_end = true;
1126 return false; 1126 return false;
1127 } 1127 }
1128 1128
1129 /* Initialize track entry. */ 1129 /* Initialize track entry. */
1130 size = filesize(fd); 1130 size = filesize(fd);
1131 tracks[track_widx].filerem = size; 1131 tracks[track_widx].filerem = size;
@@ -1135,10 +1135,10 @@ static bool audio_load_track(int offset, bool start_play, int peek_offset)
1135 //tracks[track_widx].taginfo_ready = false; 1135 //tracks[track_widx].taginfo_ready = false;
1136 tracks[track_widx].playlist_offset = peek_offset; 1136 tracks[track_widx].playlist_offset = peek_offset;
1137 last_peek_offset = peek_offset; 1137 last_peek_offset = peek_offset;
1138 1138
1139 if (buf_widx >= filebuflen) 1139 if (buf_widx >= filebuflen)
1140 buf_widx -= filebuflen; 1140 buf_widx -= filebuflen;
1141 1141
1142 /* Set default values */ 1142 /* Set default values */
1143 if (start_play) { 1143 if (start_play) {
1144 int last_codec = current_codec; 1144 int last_codec = current_codec;
@@ -1164,7 +1164,7 @@ static bool audio_load_track(int offset, bool start_play, int peek_offset)
1164 goto peek_again; 1164 goto peek_again;
1165 } 1165 }
1166 } 1166 }
1167 1167
1168 /* Load the codec. */ 1168 /* Load the codec. */
1169 tracks[track_widx].codecbuf = &filebuf[buf_widx]; 1169 tracks[track_widx].codecbuf = &filebuf[buf_widx];
1170 if (!loadcodec(start_play)) { 1170 if (!loadcodec(start_play)) {
@@ -1172,7 +1172,7 @@ static bool audio_load_track(int offset, bool start_play, int peek_offset)
1172 snprintf(msgbuf, sizeof(msgbuf)-1, "No codec for: %s", trackname); 1172 snprintf(msgbuf, sizeof(msgbuf)-1, "No codec for: %s", trackname);
1173 gui_syncsplash(HZ*2, true, msgbuf); 1173 gui_syncsplash(HZ*2, true, msgbuf);
1174 close(fd); 1174 close(fd);
1175 1175
1176 /* Set filesize to zero to indicate no file was loaded. */ 1176 /* Set filesize to zero to indicate no file was loaded. */
1177 tracks[track_widx].filesize = 0; 1177 tracks[track_widx].filesize = 0;
1178 tracks[track_widx].filerem = 0; 1178 tracks[track_widx].filerem = 0;
@@ -1220,7 +1220,7 @@ static bool audio_load_track(int offset, bool start_play, int peek_offset)
1220 break; 1220 break;
1221 } 1221 }
1222 } 1222 }
1223 1223
1224 if (start_play) { 1224 if (start_play) {
1225 track_count++; 1225 track_count++;
1226 codec_track_changed(); 1226 codec_track_changed();
@@ -1233,10 +1233,10 @@ static bool audio_load_track(int offset, bool start_play, int peek_offset)
1233 while (i < size) { 1233 while (i < size) {
1234 /* Give codecs some processing time to prevent glitches. */ 1234 /* Give codecs some processing time to prevent glitches. */
1235 yield_codecs(); 1235 yield_codecs();
1236 1236
1237 if (fill_bytesleft == 0) 1237 if (fill_bytesleft == 0)
1238 break ; 1238 break ;
1239 1239
1240 copy_n = MIN(conf_filechunk, filebuflen - buf_widx); 1240 copy_n = MIN(conf_filechunk, filebuflen - buf_widx);
1241 copy_n = MIN(size - i, copy_n); 1241 copy_n = MIN(size - i, copy_n);
1242 copy_n = MIN((int)fill_bytesleft, copy_n); 1242 copy_n = MIN((int)fill_bytesleft, copy_n);
@@ -1259,17 +1259,17 @@ static bool audio_load_track(int offset, bool start_play, int peek_offset)
1259 fill_bytesleft -= rc; 1259 fill_bytesleft -= rc;
1260 } 1260 }
1261 mutex_unlock(&mutex_bufferfill); 1261 mutex_unlock(&mutex_bufferfill);
1262 1262
1263 if (!start_play) 1263 if (!start_play)
1264 track_count++; 1264 track_count++;
1265 1265
1266 tracks[track_widx].filepos = i; 1266 tracks[track_widx].filepos = i;
1267 1267
1268 if (current_fd >= 0) { 1268 if (current_fd >= 0) {
1269 close(current_fd); 1269 close(current_fd);
1270 current_fd = -1; 1270 current_fd = -1;
1271 } 1271 }
1272 1272
1273 /* Leave the file handle open for faster buffer refill. */ 1273 /* Leave the file handle open for faster buffer refill. */
1274 if (tracks[track_widx].filerem != 0) { 1274 if (tracks[track_widx].filerem != 0) {
1275 current_fd = fd; 1275 current_fd = fd;
@@ -1279,13 +1279,13 @@ static bool audio_load_track(int offset, bool start_play, int peek_offset)
1279 close(fd); 1279 close(fd);
1280 1280
1281 strip_id3v1_tag(); 1281 strip_id3v1_tag();
1282 1282
1283 if (++track_widx >= MAX_TRACK) { 1283 if (++track_widx >= MAX_TRACK) {
1284 track_widx = 0; 1284 track_widx = 0;
1285 } 1285 }
1286 tracks[track_widx].filerem = 0; 1286 tracks[track_widx].filerem = 0;
1287 } 1287 }
1288 1288
1289 return true; 1289 return true;
1290} 1290}
1291 1291
@@ -1293,7 +1293,7 @@ static void audio_clear_track_entries(bool buffered_only)
1293{ 1293{
1294 int cur_idx, event_count; 1294 int cur_idx, event_count;
1295 int i; 1295 int i;
1296 1296
1297 cur_idx = track_widx; 1297 cur_idx = track_widx;
1298 event_count = 0; 1298 event_count = 0;
1299 for (i = 0; i < MAX_TRACK - track_count; i++) { 1299 for (i = 0; i < MAX_TRACK - track_count; i++) {
@@ -1302,14 +1302,14 @@ static void audio_clear_track_entries(bool buffered_only)
1302 1302
1303 if (tracks[cur_idx].event_sent) 1303 if (tracks[cur_idx].event_sent)
1304 event_count++; 1304 event_count++;
1305 1305
1306 if (!track_unbuffer_callback) 1306 if (!track_unbuffer_callback)
1307 memset(&tracks[cur_idx], 0, sizeof(struct track_info)); 1307 memset(&tracks[cur_idx], 0, sizeof(struct track_info));
1308 } 1308 }
1309 1309
1310 if (!track_unbuffer_callback) 1310 if (!track_unbuffer_callback)
1311 return ; 1311 return ;
1312 1312
1313 cur_idx = track_widx; 1313 cur_idx = track_widx;
1314 for (i = 0; i < MAX_TRACK - track_count; i++) { 1314 for (i = 0; i < MAX_TRACK - track_count; i++) {
1315 if (++cur_idx >= MAX_TRACK) 1315 if (++cur_idx >= MAX_TRACK)
@@ -1348,7 +1348,7 @@ static void audio_stop_playback(bool resume)
1348 close(current_fd); 1348 close(current_fd);
1349 current_fd = -1; 1349 current_fd = -1;
1350 } 1350 }
1351 1351
1352 track_count = 0; 1352 track_count = 0;
1353 /* Mark all entries null. */ 1353 /* Mark all entries null. */
1354 audio_clear_track_entries(false); 1354 audio_clear_track_entries(false);
@@ -1370,11 +1370,11 @@ static void audio_play_start(long offset)
1370 buf_widx = 0; 1370 buf_widx = 0;
1371 filebufused = 0; 1371 filebufused = 0;
1372 pcmbuf_set_boost_mode(true); 1372 pcmbuf_set_boost_mode(true);
1373 1373
1374 fill_bytesleft = filebuflen; 1374 fill_bytesleft = filebuflen;
1375 filling = true; 1375 filling = true;
1376 last_peek_offset = -1; 1376 last_peek_offset = -1;
1377 1377
1378 if (audio_load_track(offset, true, 0)) { 1378 if (audio_load_track(offset, true, 0)) {
1379 if (track_buffer_callback) { 1379 if (track_buffer_callback) {
1380 cur_ti->event_sent = true; 1380 cur_ti->event_sent = true;
@@ -1393,7 +1393,7 @@ static void generate_postbuffer_events(void)
1393{ 1393{
1394 int i; 1394 int i;
1395 int cur_ridx, event_count; 1395 int cur_ridx, event_count;
1396 1396
1397 /* At first determine how many unsent events we have. */ 1397 /* At first determine how many unsent events we have. */
1398 cur_ridx = track_ridx; 1398 cur_ridx = track_ridx;
1399 event_count = 0; 1399 event_count = 0;
@@ -1423,31 +1423,31 @@ static void generate_postbuffer_events(void)
1423static void initialize_buffer_fill(void) 1423static void initialize_buffer_fill(void)
1424{ 1424{
1425 int cur_idx, i; 1425 int cur_idx, i;
1426 1426
1427 /* Initialize only once; do not truncate the tracks. */ 1427 /* Initialize only once; do not truncate the tracks. */
1428 if (filling) 1428 if (filling)
1429 return ; 1429 return ;
1430 1430
1431 /* Save the current resume position once. */ 1431 /* Save the current resume position once. */
1432 playlist_update_resume_info(audio_current_track()); 1432 playlist_update_resume_info(audio_current_track());
1433 1433
1434 fill_bytesleft = filebuflen - filebufused; 1434 fill_bytesleft = filebuflen - filebufused;
1435 cur_ti->start_pos = ci.curpos; 1435 cur_ti->start_pos = ci.curpos;
1436 1436
1437 pcmbuf_set_boost_mode(true); 1437 pcmbuf_set_boost_mode(true);
1438 1438
1439 filling = true; 1439 filling = true;
1440 1440
1441 /* Calculate real track count after throwing away old tracks. */ 1441 /* Calculate real track count after throwing away old tracks. */
1442 cur_idx = track_ridx; 1442 cur_idx = track_ridx;
1443 for (i = 0; i < track_count; i++) { 1443 for (i = 0; i < track_count; i++) {
1444 if (cur_idx == track_widx) 1444 if (cur_idx == track_widx)
1445 break ; 1445 break ;
1446 1446
1447 if (++cur_idx >= MAX_TRACK) 1447 if (++cur_idx >= MAX_TRACK)
1448 cur_idx = 0; 1448 cur_idx = 0;
1449 } 1449 }
1450 1450
1451 track_count = i; 1451 track_count = i;
1452 if (tracks[track_widx].filesize == 0) { 1452 if (tracks[track_widx].filesize == 0) {
1453 if (--track_widx < 0) 1453 if (--track_widx < 0)
@@ -1467,11 +1467,11 @@ static void audio_check_buffer(void)
1467 || !queue_empty(&audio_queue) || !playing || ci.stop_codec 1467 || !queue_empty(&audio_queue) || !playing || ci.stop_codec
1468 || ci.reload_codec || playlist_end) && !filling) 1468 || ci.reload_codec || playlist_end) && !filling)
1469 return ; 1469 return ;
1470 1470
1471 mutex_lock(&mutex_bufferfill); 1471 mutex_lock(&mutex_bufferfill);
1472 initialize_buffer_fill(); 1472 initialize_buffer_fill();
1473 mutex_unlock(&mutex_bufferfill); 1473 mutex_unlock(&mutex_bufferfill);
1474 1474
1475 /* Limit buffering size at first run. */ 1475 /* Limit buffering size at first run. */
1476 if (conf_bufferlimit && fill_bytesleft > conf_bufferlimit 1476 if (conf_bufferlimit && fill_bytesleft > conf_bufferlimit
1477 - filebufused) { 1477 - filebufused) {
@@ -1480,17 +1480,17 @@ static void audio_check_buffer(void)
1480 else 1480 else
1481 fill_bytesleft = 0; 1481 fill_bytesleft = 0;
1482 } 1482 }
1483 1483
1484 /* Try to load remainings of the file. */ 1484 /* Try to load remainings of the file. */
1485 if (tracks[track_widx].filerem > 0) 1485 if (tracks[track_widx].filerem > 0)
1486 audio_fill_file_buffer(); 1486 audio_fill_file_buffer();
1487 1487
1488 /* Increase track write index as necessary. */ 1488 /* Increase track write index as necessary. */
1489 if (tracks[track_widx].filerem == 0 && tracks[track_widx].filesize != 0) { 1489 if (tracks[track_widx].filerem == 0 && tracks[track_widx].filesize != 0) {
1490 if (++track_widx == MAX_TRACK) 1490 if (++track_widx == MAX_TRACK)
1491 track_widx = 0; 1491 track_widx = 0;
1492 } 1492 }
1493 1493
1494 /* Load new files to fill the entire buffer. */ 1494 /* Load new files to fill the entire buffer. */
1495 if (audio_load_track(0, false, last_peek_offset + 1)) { 1495 if (audio_load_track(0, false, last_peek_offset + 1)) {
1496 if (conf_bufferlimit) 1496 if (conf_bufferlimit)
@@ -1503,13 +1503,13 @@ static void audio_check_buffer(void)
1503 { 1503 {
1504 /* Read next unbuffered track's metadata as necessary. */ 1504 /* Read next unbuffered track's metadata as necessary. */
1505 read_next_metadata(); 1505 read_next_metadata();
1506 1506
1507 generate_postbuffer_events(); 1507 generate_postbuffer_events();
1508 filling = false; 1508 filling = false;
1509 conf_bufferlimit = 0; 1509 conf_bufferlimit = 0;
1510 pcmbuf_set_boost_mode(false); 1510 pcmbuf_set_boost_mode(false);
1511 1511
1512#ifndef SIMULATOR 1512#ifndef SIMULATOR
1513 if (playing) 1513 if (playing)
1514 ata_sleep(); 1514 ata_sleep();
1515#endif 1515#endif
@@ -1533,11 +1533,12 @@ static void audio_update_trackinfo(void)
1533 codec_track_changed(); 1533 codec_track_changed();
1534 } 1534 }
1535 1535
1536 /* Automatic track change with crossfade. */ 1536 /* Automatic track change with crossfade, if not in "Track Skip Only" mode. */
1537 else if (pcmbuf_is_crossfade_enabled() && !pcmbuf_is_crossfade_active()) 1537 else if (pcmbuf_is_crossfade_enabled() && !pcmbuf_is_crossfade_active()
1538 && global_settings.crossfade != 2)
1538 { 1539 {
1539 pcmbuf_crossfade_init(false); 1540 pcmbuf_crossfade_init(false);
1540 codec_track_changed(); 1541 codec_track_changed();
1541 } 1542 }
1542 1543
1543 /* Gapless playback. */ 1544 /* Gapless playback. */
@@ -1560,7 +1561,7 @@ static int skip_next_track(bool inside_codec_thread)
1560 /* Manual track skipping. */ 1561 /* Manual track skipping. */
1561 if (new_track > 0) 1562 if (new_track > 0)
1562 last_peek_offset--; 1563 last_peek_offset--;
1563 1564
1564 /* Automatic track skipping. */ 1565 /* Automatic track skipping. */
1565 else 1566 else
1566 { 1567 {
@@ -1571,10 +1572,10 @@ static int skip_next_track(bool inside_codec_thread)
1571 last_peek_offset--; 1572 last_peek_offset--;
1572 playlist_next(1); 1573 playlist_next(1);
1573 } 1574 }
1574 1575
1575 if (++track_ridx >= MAX_TRACK) 1576 if (++track_ridx >= MAX_TRACK)
1576 track_ridx = 0; 1577 track_ridx = 0;
1577 1578
1578 /* Wait for new track data. */ 1579 /* Wait for new track data. */
1579 while (tracks[track_ridx].filesize == 0 && filling 1580 while (tracks[track_ridx].filesize == 0 && filling
1580 && !ci.stop_codec) 1581 && !ci.stop_codec)
@@ -1594,24 +1595,24 @@ static int skip_next_track(bool inside_codec_thread)
1594 } 1595 }
1595 else if (pcmbuf_is_crossfade_enabled()) 1596 else if (pcmbuf_is_crossfade_enabled())
1596 pcmbuf_crossfade_init(new_track != 0); 1597 pcmbuf_crossfade_init(new_track != 0);
1597 1598
1598 queue_post(&audio_queue, Q_AUDIO_PLAY, 0); 1599 queue_post(&audio_queue, Q_AUDIO_PLAY, 0);
1599 return SKIP_OK_DISK; 1600 return SKIP_OK_DISK;
1600 } 1601 }
1601 1602
1602 buf_ridx += cur_ti->available; 1603 buf_ridx += cur_ti->available;
1603 filebufused -= cur_ti->available; 1604 filebufused -= cur_ti->available;
1604 1605
1605 cur_ti = &tracks[track_ridx]; 1606 cur_ti = &tracks[track_ridx];
1606 buf_ridx += cur_ti->codecsize; 1607 buf_ridx += cur_ti->codecsize;
1607 filebufused -= cur_ti->codecsize; 1608 filebufused -= cur_ti->codecsize;
1608 if (buf_ridx >= filebuflen) 1609 if (buf_ridx >= filebuflen)
1609 buf_ridx -= filebuflen; 1610 buf_ridx -= filebuflen;
1610 audio_update_trackinfo(); 1611 audio_update_trackinfo();
1611 1612
1612 if (!filling) 1613 if (!filling)
1613 pcmbuf_set_boost_mode(false); 1614 pcmbuf_set_boost_mode(false);
1614 1615
1615 return SKIP_OK_RAM; 1616 return SKIP_OK_RAM;
1616} 1617}
1617 1618
@@ -1621,8 +1622,8 @@ static int skip_previous_track(bool inside_codec_thread)
1621 last_peek_offset++; 1622 last_peek_offset++;
1622 if (--track_ridx < 0) 1623 if (--track_ridx < 0)
1623 track_ridx += MAX_TRACK; 1624 track_ridx += MAX_TRACK;
1624 1625
1625 if (tracks[track_ridx].filesize == 0 || 1626 if (tracks[track_ridx].filesize == 0 ||
1626 filebufused+ci.curpos+tracks[track_ridx].filesize 1627 filebufused+ci.curpos+tracks[track_ridx].filesize
1627 /*+ (off_t)tracks[track_ridx].codecsize*/ > filebuflen) { 1628 /*+ (off_t)tracks[track_ridx].codecsize*/ > filebuflen) {
1628 logf("Loading from disk..."); 1629 logf("Loading from disk...");
@@ -1635,24 +1636,24 @@ static int skip_previous_track(bool inside_codec_thread)
1635 pcmbuf_play_stop(); 1636 pcmbuf_play_stop();
1636 else 1637 else
1637 stop_codec_flush(); 1638 stop_codec_flush();
1638 1639
1639 queue_post(&audio_queue, Q_AUDIO_PLAY, 0); 1640 queue_post(&audio_queue, Q_AUDIO_PLAY, 0);
1640 return SKIP_OK_DISK; 1641 return SKIP_OK_DISK;
1641 } 1642 }
1642 1643
1643 buf_ridx -= ci.curpos + cur_ti->codecsize; 1644 buf_ridx -= ci.curpos + cur_ti->codecsize;
1644 filebufused += ci.curpos + cur_ti->codecsize; 1645 filebufused += ci.curpos + cur_ti->codecsize;
1645 cur_ti->available = cur_ti->filesize - cur_ti->filerem; 1646 cur_ti->available = cur_ti->filesize - cur_ti->filerem;
1646 1647
1647 cur_ti = &tracks[track_ridx]; 1648 cur_ti = &tracks[track_ridx];
1648 filebufused += cur_ti->filesize; 1649 filebufused += cur_ti->filesize;
1649 cur_ti->available = cur_ti->filesize; 1650 cur_ti->available = cur_ti->filesize;
1650 if (buf_ridx < cur_ti->filesize) 1651 if (buf_ridx < cur_ti->filesize)
1651 buf_ridx += filebuflen; 1652 buf_ridx += filebuflen;
1652 buf_ridx -= cur_ti->filesize; 1653 buf_ridx -= cur_ti->filesize;
1653 1654
1654 audio_update_trackinfo(); 1655 audio_update_trackinfo();
1655 1656
1656 return SKIP_OK_RAM; 1657 return SKIP_OK_RAM;
1657} 1658}
1658 1659
@@ -1672,7 +1673,7 @@ static void audio_change_track(void)
1672 return ; 1673 return ;
1673 } 1674 }
1674 } 1675 }
1675 1676
1676 ci.reload_codec = false; 1677 ci.reload_codec = false;
1677 /* Needed for fast skipping. */ 1678 /* Needed for fast skipping. */
1678 if (cur_ti->codecsize > 0) 1679 if (cur_ti->codecsize > 0)
@@ -1692,11 +1693,11 @@ bool codec_request_next_track_callback(void)
1692 1693
1693 if (ci.stop_codec || !playing) 1694 if (ci.stop_codec || !playing)
1694 return false; 1695 return false;
1695 1696
1696#ifdef AB_REPEAT_ENABLE 1697#ifdef AB_REPEAT_ENABLE
1697 ab_end_of_track_report(); 1698 ab_end_of_track_report();
1698#endif 1699#endif
1699 1700
1700 if (!new_track) 1701 if (!new_track)
1701 pcmbuf_set_position_callback(pcmbuf_position_callback); 1702 pcmbuf_set_position_callback(pcmbuf_position_callback);
1702 1703
@@ -1707,25 +1708,25 @@ bool codec_request_next_track_callback(void)
1707 if (skip_next_track(true) != SKIP_OK_RAM) 1708 if (skip_next_track(true) != SKIP_OK_RAM)
1708 return false; 1709 return false;
1709 } 1710 }
1710 1711
1711 /* Advance to previous track. */ 1712 /* Advance to previous track. */
1712 else { 1713 else {
1713 if (skip_previous_track(true) != SKIP_OK_RAM) 1714 if (skip_previous_track(true) != SKIP_OK_RAM)
1714 return false; 1715 return false;
1715 } 1716 }
1716 1717
1717 new_track = 0; 1718 new_track = 0;
1718 ci.reload_codec = false; 1719 ci.reload_codec = false;
1719 1720
1720 logf("On-the-fly change"); 1721 logf("On-the-fly change");
1721 1722
1722 /* Check if the next codec is the same file. */ 1723 /* Check if the next codec is the same file. */
1723 if (get_codec_base_type(prev_ti->id3.codectype) != 1724 if (get_codec_base_type(prev_ti->id3.codectype) !=
1724 get_codec_base_type(cur_ti->id3.codectype)) 1725 get_codec_base_type(cur_ti->id3.codectype))
1725 { 1726 {
1726 logf("New codec:%d/%d", cur_ti->id3.codectype, 1727 logf("New codec:%d/%d", cur_ti->id3.codectype,
1727 tracks[track_ridx].id3.codectype); 1728 tracks[track_ridx].id3.codectype);
1728 1729
1729 if (cur_ti->codecsize == 0) 1730 if (cur_ti->codecsize == 0)
1730 { 1731 {
1731 logf("Loading from disk [2]..."); 1732 logf("Loading from disk [2]...");
@@ -1733,11 +1734,11 @@ bool codec_request_next_track_callback(void)
1733 } 1734 }
1734 else 1735 else
1735 ci.reload_codec = true; 1736 ci.reload_codec = true;
1736 1737
1737 return false; 1738 return false;
1738 } 1739 }
1739 1740
1740 return true; 1741 return true;
1741} 1742}
1742 1743
1743/* Invalidates all but currently playing track. */ 1744/* Invalidates all but currently playing track. */
@@ -1749,7 +1750,7 @@ void audio_invalidate_tracks(void)
1749 /* queue_post(&audio_queue, Q_AUDIO_PLAY, 0); */ 1750 /* queue_post(&audio_queue, Q_AUDIO_PLAY, 0); */
1750 return ; 1751 return ;
1751 } 1752 }
1752 1753
1753 playlist_end = false; 1754 playlist_end = false;
1754 track_count = 1; 1755 track_count = 1;
1755 last_peek_offset = 0; 1756 last_peek_offset = 0;
@@ -1799,7 +1800,7 @@ void audio_thread(void)
1799 1800
1800 /* At first initialize audio system in background. */ 1801 /* At first initialize audio system in background. */
1801 playback_init(); 1802 playback_init();
1802 1803
1803 while (1) { 1804 while (1) {
1804 if (!play_pending && queue_empty(&audio_queue)) 1805 if (!play_pending && queue_empty(&audio_queue))
1805 { 1806 {
@@ -1811,14 +1812,14 @@ void audio_thread(void)
1811 // ata_spin(); 1812 // ata_spin();
1812 sleep(1); 1813 sleep(1);
1813 } 1814 }
1814 1815
1815 queue_wait_w_tmo(&audio_queue, &ev, 0); 1816 queue_wait_w_tmo(&audio_queue, &ev, 0);
1816 if (ev.id == SYS_TIMEOUT && play_pending) 1817 if (ev.id == SYS_TIMEOUT && play_pending)
1817 { 1818 {
1818 ev.id = Q_AUDIO_PLAY; 1819 ev.id = Q_AUDIO_PLAY;
1819 ev.data = (bool *)1; 1820 ev.data = (bool *)1;
1820 } 1821 }
1821 1822
1822 switch (ev.id) { 1823 switch (ev.id) {
1823 case Q_AUDIO_PLAY: 1824 case Q_AUDIO_PLAY:
1824 /* Don't start playing immediately if user is skipping tracks 1825 /* Don't start playing immediately if user is skipping tracks
@@ -1834,7 +1835,7 @@ void audio_thread(void)
1834 } 1835 }
1835 play_pending = false; 1836 play_pending = false;
1836 last_tick = current_tick; 1837 last_tick = current_tick;
1837 1838
1838 /* Do not start crossfading if audio is paused. */ 1839 /* Do not start crossfading if audio is paused. */
1839 if (pcm_is_paused()) 1840 if (pcm_is_paused())
1840 pcmbuf_play_stop(); 1841 pcmbuf_play_stop();
@@ -1845,7 +1846,7 @@ void audio_thread(void)
1845 radio_stop(); 1846 radio_stop();
1846 } 1847 }
1847#endif 1848#endif
1848 1849
1849 logf("starting..."); 1850 logf("starting...");
1850 playing = true; 1851 playing = true;
1851 ci.stop_codec = true; 1852 ci.stop_codec = true;
@@ -1854,7 +1855,7 @@ void audio_thread(void)
1854 1855
1855 while (audio_codec_loaded) 1856 while (audio_codec_loaded)
1856 yield(); 1857 yield();
1857 1858
1858 audio_play_start((long)ev.data); 1859 audio_play_start((long)ev.data);
1859 playlist_update_resume_info(audio_current_track()); 1860 playlist_update_resume_info(audio_current_track());
1860 1861
@@ -1865,35 +1866,35 @@ void audio_thread(void)
1865 audio_stop_playback(false); 1866 audio_stop_playback(false);
1866 } 1867 }
1867 break ; 1868 break ;
1868 1869
1869 case Q_AUDIO_STOP: 1870 case Q_AUDIO_STOP:
1870 audio_stop_playback(true); 1871 audio_stop_playback(true);
1871 break ; 1872 break ;
1872 1873
1873 case Q_AUDIO_PAUSE: 1874 case Q_AUDIO_PAUSE:
1874 logf("audio_pause"); 1875 logf("audio_pause");
1875 pcmbuf_pause(true); 1876 pcmbuf_pause(true);
1876 break ; 1877 break ;
1877 1878
1878 case Q_AUDIO_RESUME: 1879 case Q_AUDIO_RESUME:
1879 logf("audio_resume"); 1880 logf("audio_resume");
1880 pcmbuf_pause(false); 1881 pcmbuf_pause(false);
1881 break ; 1882 break ;
1882 1883
1883 case Q_AUDIO_NEXT: 1884 case Q_AUDIO_NEXT:
1884 logf("audio_next"); 1885 logf("audio_next");
1885 last_tick = current_tick; 1886 last_tick = current_tick;
1886 playlist_end = false; 1887 playlist_end = false;
1887 initiate_track_change(1); 1888 initiate_track_change(1);
1888 break ; 1889 break ;
1889 1890
1890 case Q_AUDIO_PREV: 1891 case Q_AUDIO_PREV:
1891 logf("audio_prev"); 1892 logf("audio_prev");
1892 last_tick = current_tick; 1893 last_tick = current_tick;
1893 playlist_end = false; 1894 playlist_end = false;
1894 initiate_track_change(-1); 1895 initiate_track_change(-1);
1895 break; 1896 break;
1896 1897
1897 case Q_AUDIO_FF_REWIND: 1898 case Q_AUDIO_FF_REWIND:
1898 if (!playing) 1899 if (!playing)
1899 break ; 1900 break ;
@@ -1914,7 +1915,7 @@ void audio_thread(void)
1914 pcmbuf_beep(5000, 100, 2500*global_settings.beep); 1915 pcmbuf_beep(5000, 100, 2500*global_settings.beep);
1915 initiate_dir_change(1); 1916 initiate_dir_change(1);
1916 break; 1917 break;
1917 1918
1918 case Q_AUDIO_DIR_PREV: 1919 case Q_AUDIO_DIR_PREV:
1919 logf("audio_dir_prev"); 1920 logf("audio_dir_prev");
1920 playlist_end = false; 1921 playlist_end = false;
@@ -1926,14 +1927,14 @@ void audio_thread(void)
1926 case Q_AUDIO_FLUSH: 1927 case Q_AUDIO_FLUSH:
1927 audio_invalidate_tracks(); 1928 audio_invalidate_tracks();
1928 break ; 1929 break ;
1929 1930
1930 case Q_AUDIO_TRACK_CHANGED: 1931 case Q_AUDIO_TRACK_CHANGED:
1931 if (track_changed_callback) 1932 if (track_changed_callback)
1932 track_changed_callback(&cur_ti->id3); 1933 track_changed_callback(&cur_ti->id3);
1933 playlist_update_resume_info(audio_current_track()); 1934 playlist_update_resume_info(audio_current_track());
1934 pcmbuf_set_position_callback(NULL); 1935 pcmbuf_set_position_callback(NULL);
1935 break ; 1936 break ;
1936 1937
1937 case Q_AUDIO_CODEC_DONE: 1938 case Q_AUDIO_CODEC_DONE:
1938 break ; 1939 break ;
1939 1940
@@ -1957,12 +1958,12 @@ void codec_thread(void)
1957 long codecsize; 1958 long codecsize;
1958 int status; 1959 int status;
1959 int wrap; 1960 int wrap;
1960 1961
1961 while (1) { 1962 while (1) {
1962 status = 0; 1963 status = 0;
1963 queue_wait(&codec_queue, &ev); 1964 queue_wait(&codec_queue, &ev);
1964 new_track = 0; 1965 new_track = 0;
1965 1966
1966 switch (ev.id) { 1967 switch (ev.id) {
1967 case Q_CODEC_LOAD_DISK: 1968 case Q_CODEC_LOAD_DISK:
1968 ci.stop_codec = false; 1969 ci.stop_codec = false;
@@ -1972,7 +1973,7 @@ void codec_thread(void)
1972 status = codec_load_file((char *)ev.data, &ci); 1973 status = codec_load_file((char *)ev.data, &ci);
1973 mutex_unlock(&mutex_codecthread); 1974 mutex_unlock(&mutex_codecthread);
1974 break ; 1975 break ;
1975 1976
1976 case Q_CODEC_LOAD: 1977 case Q_CODEC_LOAD:
1977 logf("Codec start"); 1978 logf("Codec start");
1978 codecsize = cur_ti->codecsize; 1979 codecsize = cur_ti->codecsize;
@@ -1984,7 +1985,7 @@ void codec_thread(void)
1984 audio_stop_playback(true); 1985 audio_stop_playback(true);
1985 break ; 1986 break ;
1986 } 1987 }
1987 1988
1988 ci.stop_codec = false; 1989 ci.stop_codec = false;
1989 wrap = (long)&filebuf[filebuflen] - (long)cur_ti->codecbuf; 1990 wrap = (long)&filebuf[filebuflen] - (long)cur_ti->codecbuf;
1990 audio_codec_loaded = true; 1991 audio_codec_loaded = true;
@@ -1995,7 +1996,7 @@ void codec_thread(void)
1995 mutex_unlock(&mutex_codecthread); 1996 mutex_unlock(&mutex_codecthread);
1996 break ; 1997 break ;
1997 1998
1998#ifndef SIMULATOR 1999#ifndef SIMULATOR
1999 case SYS_USB_CONNECTED: 2000 case SYS_USB_CONNECTED:
2000 while (voice_codec_loaded) { 2001 while (voice_codec_loaded) {
2001 if (current_codec != CODEC_IDX_VOICE) 2002 if (current_codec != CODEC_IDX_VOICE)
@@ -2010,7 +2011,7 @@ void codec_thread(void)
2010 } 2011 }
2011 2012
2012 audio_codec_loaded = false; 2013 audio_codec_loaded = false;
2013 2014
2014 switch (ev.id) { 2015 switch (ev.id) {
2015 case Q_CODEC_LOAD_DISK: 2016 case Q_CODEC_LOAD_DISK:
2016 case Q_CODEC_LOAD: 2017 case Q_CODEC_LOAD:
@@ -2022,10 +2023,10 @@ void codec_thread(void)
2022 } else { 2023 } else {
2023 logf("Codec finished"); 2024 logf("Codec finished");
2024 } 2025 }
2025 2026
2026 if (playing && !ci.stop_codec) 2027 if (playing && !ci.stop_codec)
2027 audio_change_track(); 2028 audio_change_track();
2028 2029
2029 // queue_post(&audio_queue, Q_AUDIO_CODEC_DONE, (void *)status); 2030 // queue_post(&audio_queue, Q_AUDIO_CODEC_DONE, (void *)status);
2030 } 2031 }
2031 } 2032 }
@@ -2036,8 +2037,8 @@ static void reset_buffer(void)
2036 filebuf = (char *)&audiobuf[MALLOC_BUFSIZE]; 2037 filebuf = (char *)&audiobuf[MALLOC_BUFSIZE];
2037 filebuflen = audiobufend - audiobuf - MALLOC_BUFSIZE - GUARD_BUFSIZE - 2038 filebuflen = audiobufend - audiobuf - MALLOC_BUFSIZE - GUARD_BUFSIZE -
2038 (pcmbuf_get_bufsize() + get_pcmbuf_descsize() + PCMBUF_FADE_CHUNK); 2039 (pcmbuf_get_bufsize() + get_pcmbuf_descsize() + PCMBUF_FADE_CHUNK);
2039 2040
2040 2041
2041 if (talk_get_bufsize() && voice_codec_loaded) 2042 if (talk_get_bufsize() && voice_codec_loaded)
2042 { 2043 {
2043 filebuf = &filebuf[talk_get_bufsize()]; 2044 filebuf = &filebuf[talk_get_bufsize()];
@@ -2077,9 +2078,9 @@ void voice_codec_thread(void)
2077 voice_codec_loaded = true; 2078 voice_codec_loaded = true;
2078 reset_buffer(); 2079 reset_buffer();
2079 ci_voice.stop_codec = false; 2080 ci_voice.stop_codec = false;
2080 2081
2081 status = codec_load_file((char *)ev.data, &ci_voice); 2082 status = codec_load_file((char *)ev.data, &ci_voice);
2082 2083
2083 logf("Voice codec finished"); 2084 logf("Voice codec finished");
2084 audio_stop_playback(true); 2085 audio_stop_playback(true);
2085 mutex_unlock(&mutex_codecthread); 2086 mutex_unlock(&mutex_codecthread);
@@ -2088,7 +2089,7 @@ void voice_codec_thread(void)
2088 reset_buffer(); 2089 reset_buffer();
2089 break ; 2090 break ;
2090 2091
2091#ifndef SIMULATOR 2092#ifndef SIMULATOR
2092 case SYS_USB_CONNECTED: 2093 case SYS_USB_CONNECTED:
2093 logf("USB: Voice codec"); 2094 logf("USB: Voice codec");
2094 usb_acknowledge(SYS_USB_CONNECTED_ACK); 2095 usb_acknowledge(SYS_USB_CONNECTED_ACK);
@@ -2113,7 +2114,7 @@ void voice_init(void)
2113 2114
2114 if (!talk_get_bufsize()) 2115 if (!talk_get_bufsize())
2115 return ; 2116 return ;
2116 2117
2117 logf("Starting voice codec"); 2118 logf("Starting voice codec");
2118 queue_post(&voice_codec_queue, Q_CODEC_LOAD_DISK, (void *)CODEC_MPA_L3); 2119 queue_post(&voice_codec_queue, Q_CODEC_LOAD_DISK, (void *)CODEC_MPA_L3);
2119 while (!voice_codec_loaded) 2120 while (!voice_codec_loaded)
@@ -2125,19 +2126,19 @@ struct mp3entry* audio_current_track(void)
2125 const char *filename; 2126 const char *filename;
2126 const char *p; 2127 const char *p;
2127 static struct mp3entry temp_id3; 2128 static struct mp3entry temp_id3;
2128 2129
2129 if (track_count > 0 && cur_ti->taginfo_ready) 2130 if (track_count > 0 && cur_ti->taginfo_ready)
2130 return (struct mp3entry *)&cur_ti->id3; 2131 return (struct mp3entry *)&cur_ti->id3;
2131 2132
2132 filename = playlist_peek(0); 2133 filename = playlist_peek(0);
2133 if (!filename) 2134 if (!filename)
2134 filename = "No file!"; 2135 filename = "No file!";
2135 2136
2136#ifdef HAVE_TC_RAMCACHE 2137#ifdef HAVE_TC_RAMCACHE
2137 if (tagcache_fill_tags(&temp_id3, filename)) 2138 if (tagcache_fill_tags(&temp_id3, filename))
2138 return &temp_id3; 2139 return &temp_id3;
2139#endif 2140#endif
2140 2141
2141 p = strrchr(filename, '/'); 2142 p = strrchr(filename, '/');
2142 if (!p) 2143 if (!p)
2143 p = filename; 2144 p = filename;
@@ -2154,16 +2155,16 @@ struct mp3entry* audio_current_track(void)
2154struct mp3entry* audio_next_track(void) 2155struct mp3entry* audio_next_track(void)
2155{ 2156{
2156 int next_idx = track_ridx + 1; 2157 int next_idx = track_ridx + 1;
2157 2158
2158 if (track_count == 0) 2159 if (track_count == 0)
2159 return NULL; 2160 return NULL;
2160 2161
2161 if (next_idx >= MAX_TRACK) 2162 if (next_idx >= MAX_TRACK)
2162 next_idx = 0; 2163 next_idx = 0;
2163 2164
2164 if (!tracks[next_idx].taginfo_ready) 2165 if (!tracks[next_idx].taginfo_ready)
2165 return NULL; 2166 return NULL;
2166 2167
2167 return &tracks[next_idx].id3; 2168 return &tracks[next_idx].id3;
2168} 2169}
2169 2170
@@ -2173,7 +2174,7 @@ bool audio_has_changed_track(void)
2173 track_changed = false; 2174 track_changed = false;
2174 return true; 2175 return true;
2175 } 2176 }
2176 2177
2177 return false; 2178 return false;
2178} 2179}
2179 2180
@@ -2191,7 +2192,7 @@ void audio_play(long offset)
2191 stop_codec_flush(); 2192 stop_codec_flush();
2192 pcmbuf_play_stop(); 2193 pcmbuf_play_stop();
2193 } 2194 }
2194 2195
2195 queue_post(&audio_queue, Q_AUDIO_PLAY, (void *)offset); 2196 queue_post(&audio_queue, Q_AUDIO_PLAY, (void *)offset);
2196} 2197}
2197 2198
@@ -2228,11 +2229,11 @@ void audio_next(void)
2228 return ; 2229 return ;
2229 playlist_next(1); 2230 playlist_next(1);
2230 track_changed = true; 2231 track_changed = true;
2231 2232
2232 /* Force WPS to update even if audio thread is blocked spinning. */ 2233 /* Force WPS to update even if audio thread is blocked spinning. */
2233 if (mutex_bufferfill.locked) 2234 if (mutex_bufferfill.locked)
2234 cur_ti->taginfo_ready = false; 2235 cur_ti->taginfo_ready = false;
2235 2236
2236 queue_post(&audio_queue, Q_AUDIO_NEXT, 0); 2237 queue_post(&audio_queue, Q_AUDIO_NEXT, 0);
2237} 2238}
2238 2239
@@ -2246,11 +2247,11 @@ void audio_prev(void)
2246 return ; 2247 return ;
2247 playlist_next(-1); 2248 playlist_next(-1);
2248 track_changed = true; 2249 track_changed = true;
2249 2250
2250 /* Force WPS to update even if audio thread is blocked spinning. */ 2251 /* Force WPS to update even if audio thread is blocked spinning. */
2251 if (mutex_bufferfill.locked) 2252 if (mutex_bufferfill.locked)
2252 cur_ti->taginfo_ready = false; 2253 cur_ti->taginfo_ready = false;
2253 2254
2254 queue_post(&audio_queue, Q_AUDIO_PREV, 0); 2255 queue_post(&audio_queue, Q_AUDIO_PREV, 0);
2255} 2256}
2256 2257
@@ -2289,13 +2290,13 @@ void audio_error_clear(void)
2289int audio_status(void) 2290int audio_status(void)
2290{ 2291{
2291 int ret = 0; 2292 int ret = 0;
2292 2293
2293 if (playing) 2294 if (playing)
2294 ret |= AUDIO_STATUS_PLAY; 2295 ret |= AUDIO_STATUS_PLAY;
2295 2296
2296 if (pcm_is_paused()) 2297 if (pcm_is_paused())
2297 ret |= AUDIO_STATUS_PAUSE; 2298 ret |= AUDIO_STATUS_PAUSE;
2298 2299
2299 return ret; 2300 return ret;
2300} 2301}
2301 2302
@@ -2322,7 +2323,7 @@ static void mp3_set_elapsed(struct mp3entry* id3)
2322 break; 2323 break;
2323 } 2324 }
2324 } 2325 }
2325 2326
2326 i--; 2327 i--;
2327 if (i < 0) 2328 if (i < 0)
2328 i = 0; 2329 i = 0;
@@ -2335,7 +2336,7 @@ static void mp3_set_elapsed(struct mp3entry* id3)
2335 } 2336 }
2336 else 2337 else
2337 { 2338 {
2338 nextpos = 256; 2339 nextpos = 256;
2339 } 2340 }
2340 2341
2341 remainder = id3->offset - (relpos * (id3->filesize / 256)); 2342 remainder = id3->offset - (relpos * (id3->filesize / 256));
@@ -2366,7 +2367,7 @@ int mp3_get_file_pos(void)
2366{ 2367{
2367 int pos = -1; 2368 int pos = -1;
2368 struct mp3entry *id3 = audio_current_track(); 2369 struct mp3entry *id3 = audio_current_track();
2369 2370
2370 if (id3->vbr) 2371 if (id3->vbr)
2371 { 2372 {
2372 if (id3->has_toc) 2373 if (id3->has_toc)
@@ -2374,20 +2375,20 @@ int mp3_get_file_pos(void)
2374 /* Use the TOC to find the new position */ 2375 /* Use the TOC to find the new position */
2375 unsigned int percent, remainder; 2376 unsigned int percent, remainder;
2376 int curtoc, nexttoc, plen; 2377 int curtoc, nexttoc, plen;
2377 2378
2378 percent = (id3->elapsed*100)/id3->length; 2379 percent = (id3->elapsed*100)/id3->length;
2379 if (percent > 99) 2380 if (percent > 99)
2380 percent = 99; 2381 percent = 99;
2381 2382
2382 curtoc = id3->toc[percent]; 2383 curtoc = id3->toc[percent];
2383 2384
2384 if (percent < 99) 2385 if (percent < 99)
2385 nexttoc = id3->toc[percent+1]; 2386 nexttoc = id3->toc[percent+1];
2386 else 2387 else
2387 nexttoc = 256; 2388 nexttoc = 256;
2388 2389
2389 pos = (id3->filesize/256)*curtoc; 2390 pos = (id3->filesize/256)*curtoc;
2390 2391
2391 /* Use the remainder to get a more accurate position */ 2392 /* Use the remainder to get a more accurate position */
2392 remainder = (id3->elapsed*100)%id3->length; 2393 remainder = (id3->elapsed*100)%id3->length;
2393 remainder = (remainder*100)/id3->length; 2394 remainder = (remainder*100)/id3->length;
@@ -2419,7 +2420,7 @@ int mp3_get_file_pos(void)
2419 /* skip past id3v2 tag and other leading garbage */ 2420 /* skip past id3v2 tag and other leading garbage */
2420 pos = id3->first_frame_offset; 2421 pos = id3->first_frame_offset;
2421 } 2422 }
2422 return pos; 2423 return pos;
2423} 2424}
2424 2425
2425void mp3_play_data(const unsigned char* start, int size, 2426void mp3_play_data(const unsigned char* start, int size,
@@ -2460,7 +2461,7 @@ void audio_set_crossfade(int enable)
2460 seconds = global_settings.crossfade_fade_out_delay 2461 seconds = global_settings.crossfade_fade_out_delay
2461 + global_settings.crossfade_fade_out_duration; 2462 + global_settings.crossfade_fade_out_duration;
2462 } 2463 }
2463 2464
2464 /* Buffer has to be at least 2s long. */ 2465 /* Buffer has to be at least 2s long. */
2465 seconds += 2; 2466 seconds += 2;
2466 logf("buf len: %d", seconds); 2467 logf("buf len: %d", seconds);
@@ -2481,7 +2482,7 @@ void audio_set_crossfade(int enable)
2481 logf("fbuf:%dB", filebuflen); 2482 logf("fbuf:%dB", filebuflen);
2482 2483
2483 voice_init(); 2484 voice_init();
2484 2485
2485 /* Restart playback. */ 2486 /* Restart playback. */
2486 if (was_playing) { 2487 if (was_playing) {
2487 audio_play(offset); 2488 audio_play(offset);
@@ -2503,7 +2504,7 @@ void test_buffer_event(struct mp3entry *id3, bool last_track)
2503{ 2504{
2504 (void)id3; 2505 (void)id3;
2505 (void)last_track; 2506 (void)last_track;
2506 2507
2507 logf("be:%d%s", last_track, id3->path); 2508 logf("be:%d%s", last_track, id3->path);
2508} 2509}
2509 2510
@@ -2511,7 +2512,7 @@ void test_unbuffer_event(struct mp3entry *id3, bool last_track)
2511{ 2512{
2512 (void)id3; 2513 (void)id3;
2513 (void)last_track; 2514 (void)last_track;
2514 2515
2515 logf("ube:%d%s", last_track, id3->path); 2516 logf("ube:%d%s", last_track, id3->path);
2516} 2517}
2517 2518
@@ -2565,7 +2566,7 @@ static void playback_init(void)
2565 queue_wait(&audio_queue, &ev); 2566 queue_wait(&audio_queue, &ev);
2566 if (ev.id == Q_AUDIO_POSTINIT) 2567 if (ev.id == Q_AUDIO_POSTINIT)
2567 break ; 2568 break ;
2568 2569
2569#ifndef SIMULATOR 2570#ifndef SIMULATOR
2570 if (ev.id == SYS_USB_CONNECTED) 2571 if (ev.id == SYS_USB_CONNECTED)
2571 { 2572 {
@@ -2575,20 +2576,20 @@ static void playback_init(void)
2575 } 2576 }
2576#endif 2577#endif
2577 } 2578 }
2578 2579
2579 filebuf = (char *)&audiobuf[MALLOC_BUFSIZE]; 2580 filebuf = (char *)&audiobuf[MALLOC_BUFSIZE];
2580 2581
2581 /* Apply relevant settings */ 2582 /* Apply relevant settings */
2582 audio_set_buffer_margin(global_settings.buffer_margin); 2583 audio_set_buffer_margin(global_settings.buffer_margin);
2583 audio_set_crossfade(global_settings.crossfade); 2584 audio_set_crossfade(global_settings.crossfade);
2584 2585
2585 sound_settings_apply(); 2586 sound_settings_apply();
2586} 2587}
2587 2588
2588void audio_preinit(void) 2589void audio_preinit(void)
2589{ 2590{
2590 logf("playback system pre-init"); 2591 logf("playback system pre-init");
2591 2592
2592 filebufused = 0; 2593 filebufused = 0;
2593 filling = false; 2594 filling = false;
2594 current_codec = CODEC_IDX_AUDIO; 2595 current_codec = CODEC_IDX_AUDIO;
@@ -2602,7 +2603,7 @@ void audio_preinit(void)
2602 track_changed_callback = NULL; 2603 track_changed_callback = NULL;
2603 /* Just to prevent cur_ti never be anything random. */ 2604 /* Just to prevent cur_ti never be anything random. */
2604 cur_ti = &tracks[0]; 2605 cur_ti = &tracks[0];
2605 2606
2606 mutex_init(&mutex_bufferfill); 2607 mutex_init(&mutex_bufferfill);
2607 mutex_init(&mutex_codecthread); 2608 mutex_init(&mutex_codecthread);
2608 2609
diff --git a/apps/settings.c b/apps/settings.c
index 4068f78015..8c8a3ba1d5 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -203,7 +203,7 @@ static const struct bit_entry rtc_bits[] =
203 /* sound */ 203 /* sound */
204#if CONFIG_CODEC == MAS3507D 204#if CONFIG_CODEC == MAS3507D
205 {8 | SIGNED, S_O(volume), -18, "volume", NULL }, /* -78...+18 */ 205 {8 | SIGNED, S_O(volume), -18, "volume", NULL }, /* -78...+18 */
206#else 206#else
207 {8 | SIGNED, S_O(volume), -25, "volume", NULL }, /* -100...+12 / -84...0 */ 207 {8 | SIGNED, S_O(volume), -25, "volume", NULL }, /* -100...+12 / -84...0 */
208#endif 208#endif
209 {8 | SIGNED, S_O(balance), 0, "balance", NULL }, /* -100...100 */ 209 {8 | SIGNED, S_O(balance), 0, "balance", NULL }, /* -100...100 */
@@ -300,7 +300,7 @@ static const struct bit_entry rtc_bits[] =
300#endif 300#endif
301 301
302#ifdef CONFIG_BACKLIGHT 302#ifdef CONFIG_BACKLIGHT
303 {1, S_O(bl_filter_first_keypress), 303 {1, S_O(bl_filter_first_keypress),
304#ifdef HAVE_LCD_COLOR 304#ifdef HAVE_LCD_COLOR
305 true, 305 true,
306#else 306#else
@@ -308,9 +308,9 @@ static const struct bit_entry rtc_bits[] =
308#endif 308#endif
309 "backlight filters first keypress", off_on }, 309 "backlight filters first keypress", off_on },
310#ifdef HAVE_REMOTE_LCD 310#ifdef HAVE_REMOTE_LCD
311 {1, S_O(remote_bl_filter_first_keypress), false, 311 {1, S_O(remote_bl_filter_first_keypress), false,
312 "backlight filters first remote keypress", off_on }, 312 "backlight filters first remote keypress", off_on },
313#endif 313#endif
314 314
315#endif 315#endif
316 316
@@ -475,7 +475,7 @@ static const struct bit_entry hd_bits[] =
475 {1, S_O(replaygain_noclip), false, "replaygain noclip", off_on }, 475 {1, S_O(replaygain_noclip), false, "replaygain noclip", off_on },
476 {8 | SIGNED, S_O(replaygain_preamp), 0, "replaygain preamp", NULL }, 476 {8 | SIGNED, S_O(replaygain_preamp), 0, "replaygain preamp", NULL },
477 {2, S_O(beep), 0, "beep", "off,weak,moderate,strong" }, 477 {2, S_O(beep), 0, "beep", "off,weak,moderate,strong" },
478 {2, S_O(crossfade), 0, "crossfade", "off,shuffle,always"}, 478 {2, S_O(crossfade), 0, "crossfade", "off,shuffle,track skip,always"},
479 {3, S_O(crossfade_fade_in_delay), 0, "crossfade fade in delay", NULL}, 479 {3, S_O(crossfade_fade_in_delay), 0, "crossfade fade in delay", NULL},
480 {3, S_O(crossfade_fade_out_delay), 0, "crossfade fade out delay", NULL}, 480 {3, S_O(crossfade_fade_out_delay), 0, "crossfade fade out delay", NULL},
481 {4, S_O(crossfade_fade_in_duration), 0, "crossfade fade in duration", NULL}, 481 {4, S_O(crossfade_fade_in_duration), 0, "crossfade fade in duration", NULL},
@@ -511,13 +511,13 @@ static const struct bit_entry hd_bits[] =
511#endif 511#endif
512 512
513#ifdef HAVE_REMOTE_LCD 513#ifdef HAVE_REMOTE_LCD
514 {1, S_O(remote_caption_backlight), false, 514 {1, S_O(remote_caption_backlight), false,
515 "remote caption backlight", off_on }, 515 "remote caption backlight", off_on },
516#endif 516#endif
517 {4, S_O(default_codepage), 0, "default codepage", "iso8859-1,iso8859-7,iso8859-8,cp1251,iso8859-11,cp1256,iso8859-9,iso8859-2,sjis,gb2312,ksx1001,big5,utf-8,cp1256" }, 517 {4, S_O(default_codepage), 0, "default codepage", "iso8859-1,iso8859-7,iso8859-8,cp1251,iso8859-11,cp1256,iso8859-9,iso8859-2,sjis,gb2312,ksx1001,big5,utf-8,cp1256" },
518 518
519#ifdef HAVE_BACKLIGHT_BRIGHTNESS 519#ifdef HAVE_BACKLIGHT_BRIGHTNESS
520 {4, S_O(brightness), 9, "brightness", NULL }, 520 {4, S_O(brightness), 9, "brightness", NULL },
521#endif 521#endif
522 522
523#ifdef HAVE_LCD_BITMAP 523#ifdef HAVE_LCD_BITMAP
@@ -565,8 +565,8 @@ static const struct bit_entry hd_bits[] =
565#endif /* CONFIG_BACKLIGHT */ 565#endif /* CONFIG_BACKLIGHT */
566#endif /*HAVE_RECORDING*/ 566#endif /*HAVE_RECORDING*/
567#ifdef HAVE_LCD_COLOR 567#ifdef HAVE_LCD_COLOR
568 {LCD_DEPTH,S_O(fg_color),LCD_DEFAULT_FG,"foreground color","rgb"}, 568 {LCD_DEPTH,S_O(fg_color),LCD_DEFAULT_FG,"foreground color","rgb"},
569 {LCD_DEPTH,S_O(bg_color),LCD_DEFAULT_BG,"background color","rgb"}, 569 {LCD_DEPTH,S_O(bg_color),LCD_DEFAULT_BG,"background color","rgb"},
570#endif 570#endif
571 571
572#ifdef HAVE_DIRCACHE 572#ifdef HAVE_DIRCACHE
@@ -1148,7 +1148,7 @@ void settings_apply(void)
1148 dsp_set_crossfeed(global_settings.crossfeed); 1148 dsp_set_crossfeed(global_settings.crossfeed);
1149 1149
1150 dsp_set_eq(global_settings.eq_enabled); 1150 dsp_set_eq(global_settings.eq_enabled);
1151 dsp_set_eq_precut(global_settings.eq_precut); 1151 dsp_set_eq_precut(global_settings.eq_precut);
1152 /* Update all EQ bands */ 1152 /* Update all EQ bands */
1153 for(i = 0; i < 5; i++) { 1153 for(i = 0; i < 5; i++) {
1154 dsp_set_eq_coefs(i); 1154 dsp_set_eq_coefs(i);
@@ -1525,7 +1525,7 @@ static void save_cfg_table(const struct bit_entry* p_table, int count, int fd)
1525#ifdef HAVE_LCD_COLOR 1525#ifdef HAVE_LCD_COLOR
1526 else if (!strcasecmp(p_run->cfg_val, "rgb")) 1526 else if (!strcasecmp(p_run->cfg_val, "rgb"))
1527 { 1527 {
1528 fdprintf(fd, "%s: %02x%02x%02x\r\n", p_run->cfg_name, 1528 fdprintf(fd, "%s: %02x%02x%02x\r\n", p_run->cfg_name,
1529 (int)RGB_UNPACK_RED(value), 1529 (int)RGB_UNPACK_RED(value),
1530 (int)RGB_UNPACK_GREEN(value), 1530 (int)RGB_UNPACK_GREEN(value),
1531 (int)RGB_UNPACK_BLUE(value)); 1531 (int)RGB_UNPACK_BLUE(value));
@@ -1693,7 +1693,7 @@ void settings_reset(void) {
1693 global_settings.lang_file[0] = '\0'; 1693 global_settings.lang_file[0] = '\0';
1694#ifdef HAVE_LCD_COLOR 1694#ifdef HAVE_LCD_COLOR
1695 global_settings.backdrop_file[0] = '\0'; 1695 global_settings.backdrop_file[0] = '\0';
1696 1696
1697 global_settings.fg_color = LCD_DEFAULT_FG; 1697 global_settings.fg_color = LCD_DEFAULT_FG;
1698 global_settings.bg_color = LCD_DEFAULT_BG; 1698 global_settings.bg_color = LCD_DEFAULT_BG;
1699#endif 1699#endif
diff --git a/apps/settings_menu.c b/apps/settings_menu.c
index cd423ec934..b123e14946 100644
--- a/apps/settings_menu.c
+++ b/apps/settings_menu.c
@@ -1375,13 +1375,14 @@ static bool crossfade(void)
1375 static const struct opt_items names[] = { 1375 static const struct opt_items names[] = {
1376 { STR(LANG_OFF) }, 1376 { STR(LANG_OFF) },
1377 { STR(LANG_SHUFFLE) }, 1377 { STR(LANG_SHUFFLE) },
1378 { STR(LANG_TRACKSKIP) },
1378 { STR(LANG_ALWAYS) }, 1379 { STR(LANG_ALWAYS) },
1379 }; 1380 };
1380 1381
1381 bool ret; 1382 bool ret;
1382 1383
1383 ret=set_option( str(LANG_CROSSFADE_ENABLE), 1384 ret=set_option( str(LANG_CROSSFADE_ENABLE),
1384 &global_settings.crossfade, INT, names, 3, NULL); 1385 &global_settings.crossfade, INT, names, 4, NULL);
1385 1386
1386 audio_set_crossfade(global_settings.crossfade); 1387 audio_set_crossfade(global_settings.crossfade);
1387 1388