Moved genre list and access function to id3.c
[kugel-rb.git] / apps / wps.c
blobf1b0e214a765f3ebf90c13bc78610cfcbf0f2d9b
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Jerome Kuptz
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
23 #include "system.h"
24 #include "file.h"
25 #include "lcd.h"
26 #include "font.h"
27 #include "backlight.h"
28 #include "button.h"
29 #include "kernel.h"
30 #include "tree.h"
31 #include "debug.h"
32 #include "sprintf.h"
33 #include "settings.h"
34 #include "wps.h"
35 #include "wps-display.h"
36 #include "mpeg.h"
37 #include "mp3_playback.h"
38 #include "usb.h"
39 #include "status.h"
40 #include "main_menu.h"
41 #include "ata.h"
42 #include "screens.h"
43 #include "playlist.h"
44 #ifdef HAVE_LCD_BITMAP
45 #include "icons.h"
46 #include "peakmeter.h"
47 #include "action.h"
48 #endif
49 #include "lang.h"
50 #include "bookmark.h"
51 #define FF_REWIND_MAX_PERCENT 3 /* cap ff/rewind step size at max % of file */
52 /* 3% of 30min file == 54s step size */
53 #define MIN_FF_REWIND_STEP 500
55 bool keys_locked = false;
56 static bool ff_rewind = false;
57 static bool paused = false;
58 static struct mp3entry* id3 = NULL;
59 static struct mp3entry* nid3 = NULL;
60 static char current_track_path[MAX_PATH+1];
62 #if defined(HAVE_PLAYER_KEYPAD) || defined(HAVE_NEO_KEYPAD)
63 void player_change_volume(int button)
65 bool exit = false;
66 char buffer[32];
68 lcd_stop_scroll();
69 while (!exit)
71 switch (button)
73 case BUTTON_MENU | BUTTON_RIGHT:
74 case BUTTON_MENU | BUTTON_RIGHT | BUTTON_REPEAT:
75 global_settings.volume++;
76 if(global_settings.volume > mpeg_sound_max(SOUND_VOLUME))
77 global_settings.volume = mpeg_sound_max(SOUND_VOLUME);
78 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
79 wps_refresh(id3, nid3, 0, WPS_REFRESH_NON_STATIC);
80 settings_save();
81 break;
83 case BUTTON_MENU | BUTTON_LEFT:
84 case BUTTON_MENU | BUTTON_LEFT | BUTTON_REPEAT:
85 global_settings.volume--;
86 if(global_settings.volume < mpeg_sound_min(SOUND_VOLUME))
87 global_settings.volume = mpeg_sound_min(SOUND_VOLUME);
88 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
89 wps_refresh(id3, nid3, 0, WPS_REFRESH_NON_STATIC);
90 settings_save();
91 break;
93 case BUTTON_MENU | BUTTON_REL:
94 case BUTTON_MENU | BUTTON_LEFT | BUTTON_REL:
95 case BUTTON_MENU | BUTTON_RIGHT | BUTTON_REL:
96 exit = true;
97 break;
100 snprintf(buffer,sizeof(buffer),"Vol: %d %% ",
101 mpeg_val2phys(SOUND_VOLUME, global_settings.volume));
103 #ifdef HAVE_LCD_CHARCELLS
104 lcd_puts(0, 0, buffer);
105 #else
106 lcd_puts(2, 3, buffer);
107 lcd_update();
108 #endif
109 status_draw(false);
111 if (!exit)
112 button = button_get(true);
114 wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL);
116 #endif
118 void display_keylock_text(bool locked)
120 char* s;
121 lcd_stop_scroll();
122 #ifdef HAVE_LCD_CHARCELLS
123 if(locked)
124 s = str(LANG_KEYLOCK_ON_PLAYER);
125 else
126 s = str(LANG_KEYLOCK_OFF_PLAYER);
127 #else
128 if(locked)
129 s = str(LANG_KEYLOCK_ON_RECORDER);
130 else
131 s = str(LANG_KEYLOCK_OFF_RECORDER);
132 #endif
133 splash(HZ, true, s);
136 void display_mute_text(bool muted)
138 lcd_clear_display();
140 #ifdef HAVE_LCD_CHARCELLS
141 if (muted)
142 lcd_puts(0, 0, str(LANG_MUTE_ON_PLAYER));
143 else
144 lcd_puts(0, 0, str(LANG_MUTE_OFF_PLAYER));
145 #else
146 if (muted)
147 lcd_puts(2, 3, str(LANG_MUTE_ON_RECORDER));
148 else
149 lcd_puts(2, 3, str(LANG_MUTE_OFF_RECORDER));
150 lcd_update();
151 #endif
153 sleep(HZ);
156 bool browse_id3(void)
158 int button;
159 int menu_pos = 0;
160 int menu_max = 8;
161 bool exit = false;
162 char scroll_text[MAX_PATH];
164 if (!(mpeg_status() & MPEG_STATUS_PLAY))
165 return false;
167 while (!exit)
169 lcd_clear_display();
171 switch (menu_pos)
173 case 0:
174 lcd_puts(0, 0, str(LANG_ID3_TITLE));
175 lcd_puts_scroll(0, 1, id3->title ? id3->title :
176 (char*)str(LANG_ID3_NO_TITLE));
177 break;
179 case 1:
180 lcd_puts(0, 0, str(LANG_ID3_ARTIST));
181 lcd_puts_scroll(0, 1,
182 id3->artist ? id3->artist :
183 (char*)str(LANG_ID3_NO_ARTIST));
184 break;
186 case 2:
187 lcd_puts(0, 0, str(LANG_ID3_ALBUM));
188 lcd_puts_scroll(0, 1, id3->album ? id3->album :
189 (char*)str(LANG_ID3_NO_ALBUM));
190 break;
192 case 3:
193 lcd_puts(0, 0, str(LANG_ID3_TRACKNUM));
195 if (id3->tracknum) {
196 snprintf(scroll_text,sizeof(scroll_text), "%d",
197 id3->tracknum);
198 lcd_puts_scroll(0, 1, scroll_text);
200 else
201 lcd_puts_scroll(0, 1, str(LANG_ID3_NO_TRACKNUM));
202 break;
204 case 4:
205 lcd_puts(0, 0, str(LANG_ID3_GENRE));
206 lcd_puts_scroll(0, 1,
207 id3_get_genre(id3) ?
208 id3_get_genre(id3) :
209 (char*)str(LANG_ID3_NO_INFO));
210 break;
212 case 5:
213 lcd_puts(0, 0, str(LANG_ID3_YEAR));
214 if (id3->year) {
215 snprintf(scroll_text,sizeof(scroll_text), "%d",
216 id3->year);
217 lcd_puts_scroll(0, 1, scroll_text);
219 else
220 lcd_puts_scroll(0, 1, str(LANG_ID3_NO_INFO));
221 break;
223 case 6:
224 lcd_puts(0, 0, str(LANG_ID3_LENGHT));
225 snprintf(scroll_text,sizeof(scroll_text), "%d:%02d",
226 id3->length / 60000,
227 id3->length % 60000 / 1000 );
228 lcd_puts(0, 1, scroll_text);
229 break;
231 case 7:
232 lcd_puts(0, 0, str(LANG_ID3_PLAYLIST));
233 snprintf(scroll_text,sizeof(scroll_text), "%d/%d",
234 playlist_get_display_index(), playlist_amount());
235 lcd_puts_scroll(0, 1, scroll_text);
236 break;
239 case 8:
240 lcd_puts(0, 0, str(LANG_ID3_BITRATE));
241 snprintf(scroll_text,sizeof(scroll_text), "%d kbps",
242 id3->bitrate);
243 lcd_puts(0, 1, scroll_text);
244 break;
246 case 9:
247 lcd_puts(0, 0, str(LANG_ID3_FRECUENCY));
248 snprintf(scroll_text,sizeof(scroll_text), "%d Hz",
249 id3->frequency);
250 lcd_puts(0, 1, scroll_text);
251 break;
253 case 10:
254 lcd_puts(0, 0, str(LANG_ID3_PATH));
255 lcd_puts_scroll(0, 1, id3->path);
256 break;
258 lcd_update();
260 button = button_get(true);
262 switch(button)
264 case BUTTON_LEFT:
265 #ifdef HAVE_RECORDER_KEYPAD
266 case BUTTON_UP:
267 #endif
268 if (menu_pos > 0)
269 menu_pos--;
270 else
271 menu_pos = menu_max;
272 break;
274 case BUTTON_RIGHT:
275 #ifdef HAVE_RECORDER_KEYPAD
276 case BUTTON_DOWN:
277 #endif
278 if (menu_pos < menu_max)
279 menu_pos++;
280 else
281 menu_pos = 0;
282 break;
284 case BUTTON_REPEAT:
285 break;
287 #ifdef BUTTON_STOP
288 case BUTTON_STOP:
289 #else
290 case BUTTON_OFF:
291 #endif
292 case BUTTON_PLAY:
293 lcd_stop_scroll();
294 /* eat release event */
295 button_get(true);
296 exit = true;
297 break;
299 case SYS_USB_CONNECTED:
300 status_set_playmode(STATUS_STOP);
301 usb_screen();
302 return true;
303 break;
306 return false;
309 static bool ffwd_rew(int button)
311 static int ff_rew_steps[] = {
312 1000, 2000, 3000, 4000,
313 5000, 6000, 8000, 10000,
314 15000, 20000, 25000, 30000,
315 45000, 60000
318 unsigned int step = 0; /* current ff/rewind step */
319 unsigned int max_step = 0; /* maximum ff/rewind step */
320 int ff_rewind_count = 0; /* current ff/rewind count (in ticks) */
321 int direction = 1; /* forward=1 or backward=-1 */
322 long accel_tick = 0; /* next time at which to bump the step size */
323 bool exit = false;
324 bool usb = false;
326 while (!exit) {
327 switch ( button ) {
328 case BUTTON_LEFT | BUTTON_REPEAT:
329 case BUTTON_RIGHT | BUTTON_REPEAT:
330 if (ff_rewind)
332 if (direction == 1)
334 /* fast forwarding, calc max step relative to end */
335 max_step =
336 (id3->length - (id3->elapsed + ff_rewind_count)) *
337 FF_REWIND_MAX_PERCENT / 100;
339 else
341 /* rewinding, calc max step relative to start */
342 max_step = (id3->elapsed + ff_rewind_count) *
343 FF_REWIND_MAX_PERCENT / 100;
346 max_step = MAX(max_step, MIN_FF_REWIND_STEP);
348 if (step > max_step)
349 step = max_step;
351 ff_rewind_count += step * direction;
353 if (global_settings.ff_rewind_accel != 0 &&
354 current_tick >= accel_tick)
356 step *= 2;
357 accel_tick = current_tick +
358 global_settings.ff_rewind_accel*HZ;
361 else
363 if ( (mpeg_status() & MPEG_STATUS_PLAY) &&
364 id3 && id3->length )
366 if (!paused)
367 mpeg_pause();
368 #ifdef HAVE_PLAYER_KEYPAD
369 lcd_stop_scroll();
370 #endif
371 direction = (button & BUTTON_RIGHT) ? 1 : -1;
373 if (direction > 0)
374 status_set_playmode(STATUS_FASTFORWARD);
375 else
376 status_set_playmode(STATUS_FASTBACKWARD);
378 ff_rewind = true;
380 step = ff_rew_steps[global_settings.ff_rewind_min_step];
382 accel_tick = current_tick +
383 global_settings.ff_rewind_accel*HZ;
385 else
386 break;
389 if (direction > 0) {
390 if ((id3->elapsed + ff_rewind_count) > id3->length)
391 ff_rewind_count = id3->length - id3->elapsed;
393 else {
394 if ((int)(id3->elapsed + ff_rewind_count) < 0)
395 ff_rewind_count = -id3->elapsed;
398 if(wps_time_countup == false)
399 wps_refresh(id3, nid3, -ff_rewind_count,
400 WPS_REFRESH_PLAYER_PROGRESS |
401 WPS_REFRESH_DYNAMIC);
402 else
403 wps_refresh(id3, nid3, ff_rewind_count,
404 WPS_REFRESH_PLAYER_PROGRESS |
405 WPS_REFRESH_DYNAMIC);
407 break;
409 case BUTTON_LEFT | BUTTON_REL:
410 case BUTTON_RIGHT | BUTTON_REL:
411 mpeg_ff_rewind(id3->elapsed+ff_rewind_count);
412 ff_rewind_count = 0;
413 ff_rewind = false;
414 if (paused)
415 status_set_playmode(STATUS_PAUSE);
416 else {
417 mpeg_resume();
418 status_set_playmode(STATUS_PLAY);
420 #ifdef HAVE_LCD_CHARCELLS
421 wps_display(id3, nid3);
422 #endif
423 exit = true;
424 break;
426 case SYS_USB_CONNECTED:
427 status_set_playmode(STATUS_STOP);
428 usb_screen();
429 usb = true;
430 exit = true;
431 break;
433 if (!exit)
434 button = button_get(true);
437 /* let mpeg thread update id3->elapsed before calling wps_refresh */
438 yield();
439 wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL);
440 return usb;
443 static bool update(void)
445 bool track_changed = mpeg_has_changed_track();
446 bool retcode = false;
448 nid3 = mpeg_next_track();
449 if (track_changed)
451 lcd_stop_scroll();
452 id3 = mpeg_current_track();
453 if (wps_display(id3, nid3))
454 retcode = true;
455 else
456 wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL);
458 if (id3)
459 memcpy(current_track_path, id3->path, sizeof(current_track_path));
462 if (id3)
463 wps_refresh(id3, nid3, 0, WPS_REFRESH_NON_STATIC);
465 status_draw(false);
467 /* save resume data */
468 if ( id3 &&
469 global_settings.resume &&
470 global_settings.resume_offset != id3->offset ) {
471 DEBUGF("R%X,%X (%X)\n", global_settings.resume_offset,
472 id3->offset,id3);
474 if (!playlist_get_resume_info(&global_settings.resume_index))
476 global_settings.resume_offset = id3->offset;
477 settings_save();
480 else if ( !id3 && track_changed ) {
481 global_settings.resume_index = -1;
482 global_settings.resume_offset = -1;
483 settings_save();
486 return retcode;
489 static bool menu(void)
491 static bool muted = false;
492 bool exit = false;
493 int last_button = 0;
495 #ifdef HAVE_LCD_CHARCELLS
496 status_set_param(true);
497 status_draw(false);
498 #endif
500 while (!exit) {
501 int button = button_get(true);
503 switch ( button ) {
504 /* go into menu */
505 #ifdef HAVE_RECORDER_KEYPAD
506 case BUTTON_F1 | BUTTON_REL:
507 #else
508 case BUTTON_MENU | BUTTON_REL:
509 #endif
510 exit = true;
511 if ( !last_button && !keys_locked ) {
512 lcd_stop_scroll();
514 if (main_menu())
515 return true;
516 #ifdef HAVE_LCD_BITMAP
517 if(global_settings.statusbar)
518 lcd_setmargins(0, STATUSBAR_HEIGHT);
519 else
520 lcd_setmargins(0, 0);
521 #endif
523 break;
525 /* mute */
526 #ifdef BUTTON_MENU
527 case BUTTON_MENU | BUTTON_PLAY:
528 #else
529 case BUTTON_F1 | BUTTON_PLAY:
530 #endif
531 if ( muted )
532 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
533 else
534 mpeg_sound_set(SOUND_VOLUME, 0);
535 muted = !muted;
536 #ifdef HAVE_LCD_CHARCELLS
537 status_set_param(false);
538 #endif
539 display_mute_text(muted);
540 break;
542 /* key lock */
543 #ifdef HAVE_RECORDER_KEYPAD
544 case BUTTON_F1 | BUTTON_DOWN:
545 #else
546 case BUTTON_MENU | BUTTON_STOP:
547 #endif
548 keys_locked = !keys_locked;
549 display_keylock_text(keys_locked);
550 exit = true;
551 while (button_get(false)); /* clear button queue */
552 break;
554 #ifdef BUTTON_MENU
555 /* change volume */
556 case BUTTON_MENU | BUTTON_LEFT:
557 case BUTTON_MENU | BUTTON_LEFT | BUTTON_REPEAT:
558 case BUTTON_MENU | BUTTON_RIGHT:
559 case BUTTON_MENU | BUTTON_RIGHT | BUTTON_REPEAT:
560 player_change_volume(button);
561 exit = true;
562 break;
564 /* show id3 tags */
565 #ifdef BUTTON_ON
566 case BUTTON_MENU | BUTTON_ON:
567 status_set_param(true);
568 status_set_audio(true);
569 #endif
570 #else
571 case BUTTON_F1 | BUTTON_ON:
572 #endif
573 lcd_clear_display();
574 lcd_puts(0, 0, str(LANG_ID3_INFO));
575 lcd_puts(0, 1, str(LANG_ID3_SCREEN));
576 lcd_update();
577 sleep(HZ);
579 if(browse_id3())
580 return true;
581 #ifdef HAVE_PLAYER_KEYPAD
582 status_set_param(false);
583 status_set_audio(true);
584 #endif
585 exit = true;
586 break;
588 case SYS_USB_CONNECTED:
589 status_set_playmode(STATUS_STOP);
590 usb_screen();
591 return true;
593 last_button = button;
596 #ifdef HAVE_LCD_CHARCELLS
597 status_set_param(false);
598 #endif
600 return false;
603 static void fade(bool fade_in)
605 if (fade_in) {
606 /* fade in */
607 int current_volume = 20;
609 /* zero out the sound */
610 mpeg_sound_set(SOUND_VOLUME, current_volume);
612 sleep(HZ/10); /* let mpeg thread run */
613 mpeg_resume();
615 while (current_volume < global_settings.volume) {
616 current_volume += 2;
617 sleep(1);
618 mpeg_sound_set(SOUND_VOLUME, current_volume);
620 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
622 else {
623 /* fade out */
624 int current_volume = global_settings.volume;
626 while (current_volume > 20) {
627 current_volume -= 2;
628 sleep(1);
629 mpeg_sound_set(SOUND_VOLUME, current_volume);
631 mpeg_pause();
632 sleep(HZ/5); /* let mpeg thread run */
634 /* reset volume to what it was before the fade */
635 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
640 /* demonstrates showing different formats from playtune */
641 int wps_show(void)
643 int button = 0, lastbutton = 0;
644 bool ignore_keyup = true;
645 bool restore = false;
646 bool exit = false;
647 bool update_track = false;
649 id3 = nid3 = NULL;
650 current_track_path[0] = '\0';
652 #ifdef HAVE_LCD_CHARCELLS
653 status_set_audio(true);
654 status_set_param(false);
655 #else
656 if(global_settings.statusbar)
657 lcd_setmargins(0, STATUSBAR_HEIGHT);
658 else
659 lcd_setmargins(0, 0);
660 #endif
662 ff_rewind = false;
664 if(mpeg_status() & MPEG_STATUS_PLAY)
666 id3 = mpeg_current_track();
667 nid3 = mpeg_next_track();
668 if (id3) {
669 if (wps_display(id3, nid3))
670 return 0;
671 wps_refresh(id3, nid3, 0, WPS_REFRESH_ALL);
673 memcpy(current_track_path, id3->path, sizeof(current_track_path));
676 restore = true;
679 while ( 1 )
681 bool mpeg_paused = (mpeg_status() & MPEG_STATUS_PAUSE)?true:false;
682 status_set_playmode(paused ? STATUS_PAUSE : STATUS_PLAY);
684 /* did someone else (i.e power thread) change mpeg pause mode? */
685 if (paused != mpeg_paused) {
686 paused = mpeg_paused;
688 /* if another thread paused mpeg, we are probably in car mode,
689 about to shut down. lets save the settings. */
690 if (paused && global_settings.resume) {
691 settings_save();
692 #ifndef HAVE_RTC
693 ata_flush();
694 #endif
698 #ifdef HAVE_LCD_BITMAP
699 /* when the peak meter is enabled we want to have a
700 few extra updates to make it look smooth. On the
701 other hand we don't want to waste energy if it
702 isn't displayed */
703 if (peak_meter_enabled) {
704 int i;
706 /* In high performance mode we read out the mas as
707 often as we can. There is no sleep for cpu */
708 if (global_settings.peak_meter_performance) {
709 long next_refresh = current_tick;
710 long next_big_refresh = current_tick + HZ / 5;
711 button = BUTTON_NONE;
712 while (!TIME_AFTER(current_tick, next_big_refresh)) {
713 button = button_get(false);
714 if (button != BUTTON_NONE) {
715 break;
717 peak_meter_peek();
718 sleep(1);
720 if (TIME_AFTER(current_tick, next_refresh)) {
721 wps_refresh(id3, nid3, 0, WPS_REFRESH_PEAK_METER);
722 next_refresh = current_tick + HZ / peak_meter_fps;
727 /* In energy saver mode the cpu may sleep a
728 little bit while waiting for buttons */
729 else {
730 for (i = 0; i < 4; i++) {
731 button = button_get_w_tmo(HZ / peak_meter_fps);
732 if (button != 0) {
733 break;
735 wps_refresh(id3, nid3, 0, WPS_REFRESH_PEAK_METER);
740 /* The peak meter is disabled
741 -> no additional screen updates needed */
742 else {
743 button = button_get_w_tmo(HZ/5);
745 #else
746 button = button_get_w_tmo(HZ/5);
747 #endif
749 /* discard first event if it's a button release */
750 if (button && ignore_keyup)
752 ignore_keyup = false;
753 if (button & BUTTON_REL && button != SYS_USB_CONNECTED)
754 continue;
757 /* ignore non-remote buttons when keys are locked */
758 if (keys_locked &&
759 #ifdef HAVE_RECORDER_KEYPAD
760 ! ((button & BUTTON_F1) ||
761 #else
762 ! ((button & BUTTON_MENU) ||
763 #endif
764 (button == BUTTON_NONE) ||
765 (button == SYS_USB_CONNECTED)
766 #ifdef BUTTON_REMOTE
767 || (button & BUTTON_REMOTE)
768 #endif
771 while (button_get(false)); /* clear button queue */
772 display_keylock_text(true);
773 restore = true;
774 continue;
777 /* Exit if mpeg has stopped playing. This can happen if using the
778 sleep timer with the charger plugged or if starting a recording
779 from F1 */
780 if (!mpeg_status())
781 exit = true;
783 switch(button)
785 #ifdef BUTTON_ON
786 case BUTTON_ON:
787 #ifdef HAVE_RECORDER_KEYPAD
788 switch (on_screen()) {
789 case 2:
790 /* usb connected? */
791 return SYS_USB_CONNECTED;
793 case 1:
794 /* was on_screen used? */
795 restore = true;
797 /* pause may have been turned off by pitch screen */
798 if (paused && !(mpeg_status() & MPEG_STATUS_PAUSE)) {
799 paused = false;
800 status_set_playmode(STATUS_PLAY);
802 break;
804 case 0:
805 /* otherwise, exit to browser */
806 #else
807 status_set_record(false);
808 status_set_audio(false);
809 #endif
810 lcd_stop_scroll();
812 /* set dir browser to current playing song */
813 if (global_settings.browse_current &&
814 current_track_path[0] != '\0')
815 set_current_file(current_track_path);
817 return 0;
818 #ifdef HAVE_RECORDER_KEYPAD
820 break;
821 #endif
822 #endif /* BUTTON_ON */
823 /* play/pause */
824 case BUTTON_PLAY:
825 #ifdef BUTTON_RC_PLAY
826 case BUTTON_RC_PLAY:
827 #endif
828 if ( paused )
830 paused = false;
831 status_set_playmode(STATUS_PLAY);
832 if ( global_settings.fade_on_stop )
833 fade(1);
834 else
835 mpeg_resume();
837 else
839 paused = true;
840 status_set_playmode(STATUS_PAUSE);
841 if ( global_settings.fade_on_stop )
842 fade(0);
843 else
844 mpeg_pause();
845 if (global_settings.resume) {
846 settings_save();
847 #ifndef HAVE_RTC
848 ata_flush();
849 #endif
852 break;
854 /* volume up */
855 #ifdef HAVE_RECORDER_KEYPAD
856 case BUTTON_UP:
857 case BUTTON_UP | BUTTON_REPEAT:
858 #endif
859 #ifdef BUTTON_RC_VOL_UP
860 case BUTTON_RC_VOL_UP:
861 #endif
862 global_settings.volume++;
863 if(global_settings.volume > mpeg_sound_max(SOUND_VOLUME))
864 global_settings.volume = mpeg_sound_max(SOUND_VOLUME);
865 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
866 status_draw(false);
867 settings_save();
868 break;
870 /* volume down */
871 #ifdef HAVE_RECORDER_KEYPAD
872 case BUTTON_DOWN:
873 case BUTTON_DOWN | BUTTON_REPEAT:
874 #endif
875 #ifdef BUTTON_RC_VOL_DOWN
876 case BUTTON_RC_VOL_DOWN:
877 #endif
878 global_settings.volume--;
879 if(global_settings.volume < mpeg_sound_min(SOUND_VOLUME))
880 global_settings.volume = mpeg_sound_min(SOUND_VOLUME);
881 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
882 status_draw(false);
883 settings_save();
884 break;
886 /* fast forward / rewind */
887 case BUTTON_LEFT | BUTTON_REPEAT:
888 case BUTTON_RIGHT | BUTTON_REPEAT:
889 ffwd_rew(button);
890 break;
892 /* prev / restart */
893 #ifdef BUTTON_RC_LEFT
894 case BUTTON_RC_LEFT:
895 #endif
896 case BUTTON_LEFT | BUTTON_REL:
897 #ifdef HAVE_RECORDER_KEYPAD
898 if ((button == (BUTTON_LEFT | BUTTON_REL)) &&
899 (lastbutton != BUTTON_LEFT ))
900 break;
901 #endif
902 if (!id3 || (id3->elapsed < 3*1000)) {
903 mpeg_prev();
905 else {
906 if (!paused)
907 mpeg_pause();
909 mpeg_ff_rewind(0);
911 if (!paused)
912 mpeg_resume();
914 break;
916 /* next */
917 #ifdef BUTTON_RC_RIGHT
918 case BUTTON_RC_RIGHT:
919 #endif
920 case BUTTON_RIGHT | BUTTON_REL:
921 #ifdef HAVE_RECORDER_KEYPAD
922 if ((button == (BUTTON_RIGHT | BUTTON_REL)) &&
923 (lastbutton != BUTTON_RIGHT))
924 break;
925 #endif
926 mpeg_next();
927 break;
929 /* menu key functions */
930 #ifdef BUTTON_MENU
931 case BUTTON_MENU:
932 #else
933 case BUTTON_F1:
934 #endif
935 if (menu())
936 return SYS_USB_CONNECTED;
938 update_track = true;
939 restore = true;
940 break;
942 #ifdef HAVE_RECORDER_KEYPAD
943 /* play settings */
944 case BUTTON_F2:
945 if (quick_screen(CONTEXT_WPS, BUTTON_F2))
946 return SYS_USB_CONNECTED;
947 restore = true;
948 break;
950 /* screen settings */
951 case BUTTON_F3:
952 if (quick_screen(CONTEXT_WPS, BUTTON_F3))
953 return SYS_USB_CONNECTED;
954 restore = true;
955 break;
956 #endif
958 /* stop and exit wps */
959 #ifdef BUTTON_OFF
960 case BUTTON_OFF | BUTTON_REL:
961 #else
962 case BUTTON_STOP | BUTTON_REL:
963 if ( lastbutton != BUTTON_STOP )
964 break;
965 #endif
966 #ifdef BUTTON_RC_STOP
967 case BUTTON_RC_STOP:
968 #endif
969 exit = true;
970 break;
972 case SYS_USB_CONNECTED:
973 status_set_playmode(STATUS_STOP);
974 usb_screen();
975 return SYS_USB_CONNECTED;
977 case BUTTON_NONE: /* Timeout */
978 update_track = true;
979 break;
982 if (update_track)
984 if (update())
986 /* set dir browser to current playing song */
987 if (global_settings.browse_current &&
988 current_track_path[0] != '\0')
989 set_current_file(current_track_path);
991 return 0;
993 update_track = false;
996 if (exit) {
997 #ifdef HAVE_LCD_CHARCELLS
998 status_set_record(false);
999 status_set_audio(false);
1000 #endif
1001 if (global_settings.fade_on_stop)
1002 fade(0);
1004 lcd_stop_scroll();
1005 bookmark_autobookmark();
1006 mpeg_stop();
1007 status_set_playmode(STATUS_STOP);
1009 /* Keys can be locked when exiting, so either unlock here
1010 or implement key locking in tree.c too */
1011 keys_locked=false;
1013 /* set dir browser to current playing song */
1014 if (global_settings.browse_current &&
1015 current_track_path[0] != '\0')
1016 set_current_file(current_track_path);
1018 return 0;
1021 if ( button )
1022 ata_spin();
1024 if (restore) {
1025 restore = false;
1026 if (wps_display(id3, nid3))
1028 /* set dir browser to current playing song */
1029 if (global_settings.browse_current &&
1030 current_track_path[0] != '\0')
1031 set_current_file(current_track_path);
1033 return 0;
1036 if (id3)
1037 wps_refresh(id3, nid3, 0, WPS_REFRESH_NON_STATIC);
1039 if(button != BUTTON_NONE)
1040 lastbutton = button;
1042 return 0; /* unreachable - just to reduce compiler warnings */