Added Benjamin Metzlers bookmarking feature (patch #669440)
[kugel-rb.git] / apps / wps.c
blob09eeef4361a2cfcfdcab4d5c17017a9853f62be1
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 "file.h"
24 #include "lcd.h"
25 #include "font.h"
26 #include "backlight.h"
27 #include "button.h"
28 #include "kernel.h"
29 #include "tree.h"
30 #include "debug.h"
31 #include "sprintf.h"
32 #include "settings.h"
33 #include "wps.h"
34 #include "wps-display.h"
35 #include "mpeg.h"
36 #include "mp3_playback.h"
37 #include "usb.h"
38 #include "status.h"
39 #include "main_menu.h"
40 #include "ata.h"
41 #include "screens.h"
42 #include "playlist.h"
43 #ifdef HAVE_LCD_BITMAP
44 #include "icons.h"
45 #include "peakmeter.h"
46 #endif
47 #include "lang.h"
48 #include "bookmark.h"
49 #define FF_REWIND_MAX_PERCENT 3 /* cap ff/rewind step size at max % of file */
50 /* 3% of 30min file == 54s step size */
52 bool keys_locked = false;
53 static bool ff_rewind = false;
54 static bool paused = false;
55 static struct mp3entry* id3 = NULL;
56 static char current_track_path[MAX_PATH+1];
58 #if defined(HAVE_PLAYER_KEYPAD) || defined(HAVE_NEO_KEYPAD)
59 void player_change_volume(int button)
61 bool exit = false;
62 char buffer[32];
64 lcd_stop_scroll();
65 while (!exit)
67 switch (button)
69 case BUTTON_MENU | BUTTON_RIGHT:
70 case BUTTON_MENU | BUTTON_RIGHT | BUTTON_REPEAT:
71 global_settings.volume++;
72 if(global_settings.volume > mpeg_sound_max(SOUND_VOLUME))
73 global_settings.volume = mpeg_sound_max(SOUND_VOLUME);
74 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
75 wps_refresh(id3, 0, WPS_REFRESH_NON_STATIC);
76 settings_save();
77 break;
79 case BUTTON_MENU | BUTTON_LEFT:
80 case BUTTON_MENU | BUTTON_LEFT | BUTTON_REPEAT:
81 global_settings.volume--;
82 if(global_settings.volume < mpeg_sound_min(SOUND_VOLUME))
83 global_settings.volume = mpeg_sound_min(SOUND_VOLUME);
84 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
85 wps_refresh(id3, 0, WPS_REFRESH_NON_STATIC);
86 settings_save();
87 break;
89 case BUTTON_MENU | BUTTON_REL:
90 case BUTTON_MENU | BUTTON_LEFT | BUTTON_REL:
91 case BUTTON_MENU | BUTTON_RIGHT | BUTTON_REL:
92 exit = true;
93 break;
96 snprintf(buffer,sizeof(buffer),"Vol: %d %% ",
97 mpeg_val2phys(SOUND_VOLUME, global_settings.volume));
99 #ifdef HAVE_LCD_CHARCELLS
100 lcd_puts(0, 0, buffer);
101 #else
102 lcd_puts(2, 3, buffer);
103 lcd_update();
104 #endif
105 status_draw(false);
107 if (!exit)
108 button = button_get(true);
110 wps_refresh(id3,0, WPS_REFRESH_ALL);
112 #endif
114 void display_keylock_text(bool locked)
116 char* s;
117 lcd_stop_scroll();
118 #ifdef HAVE_LCD_CHARCELLS
119 if(locked)
120 s = str(LANG_KEYLOCK_ON_PLAYER);
121 else
122 s = str(LANG_KEYLOCK_OFF_PLAYER);
123 #else
124 if(locked)
125 s = str(LANG_KEYLOCK_ON_RECORDER);
126 else
127 s = str(LANG_KEYLOCK_OFF_RECORDER);
128 #endif
129 splash(HZ, true, s);
132 void display_mute_text(bool muted)
134 lcd_clear_display();
136 #ifdef HAVE_LCD_CHARCELLS
137 if (muted)
138 lcd_puts(0, 0, str(LANG_MUTE_ON_PLAYER));
139 else
140 lcd_puts(0, 0, str(LANG_MUTE_OFF_PLAYER));
141 #else
142 if (muted)
143 lcd_puts(2, 3, str(LANG_MUTE_ON_RECORDER));
144 else
145 lcd_puts(2, 3, str(LANG_MUTE_OFF_RECORDER));
146 lcd_update();
147 #endif
149 sleep(HZ);
152 bool browse_id3(void)
154 int button;
155 int menu_pos = 0;
156 int menu_max = 8;
157 bool exit = false;
158 char scroll_text[MAX_PATH];
160 if (!(mpeg_status() & MPEG_STATUS_PLAY))
161 return false;
163 while (!exit)
165 lcd_clear_display();
167 switch (menu_pos)
169 case 0:
170 lcd_puts(0, 0, str(LANG_ID3_TITLE));
171 lcd_puts_scroll(0, 1, id3->title ? id3->title :
172 (char*)str(LANG_ID3_NO_TITLE));
173 break;
175 case 1:
176 lcd_puts(0, 0, str(LANG_ID3_ARTIST));
177 lcd_puts_scroll(0, 1,
178 id3->artist ? id3->artist :
179 (char*)str(LANG_ID3_NO_ARTIST));
180 break;
182 case 2:
183 lcd_puts(0, 0, str(LANG_ID3_ALBUM));
184 lcd_puts_scroll(0, 1, id3->album ? id3->album :
185 (char*)str(LANG_ID3_NO_ALBUM));
186 break;
188 case 3:
189 lcd_puts(0, 0, str(LANG_ID3_TRACKNUM));
191 if (id3->tracknum) {
192 snprintf(scroll_text,sizeof(scroll_text), "%d",
193 id3->tracknum);
194 lcd_puts_scroll(0, 1, scroll_text);
196 else
197 lcd_puts_scroll(0, 1, str(LANG_ID3_NO_TRACKNUM));
198 break;
200 case 4:
201 lcd_puts(0, 0, str(LANG_ID3_GENRE));
202 lcd_puts_scroll(0, 1,
203 wps_get_genre(id3->genre) ?
204 wps_get_genre(id3->genre) :
205 (char*)str(LANG_ID3_NO_INFO));
206 break;
208 case 5:
209 lcd_puts(0, 0, str(LANG_ID3_YEAR));
210 if (id3->year) {
211 snprintf(scroll_text,sizeof(scroll_text), "%d",
212 id3->year);
213 lcd_puts_scroll(0, 1, scroll_text);
215 else
216 lcd_puts_scroll(0, 1, str(LANG_ID3_NO_INFO));
217 break;
219 case 6:
220 lcd_puts(0, 0, str(LANG_ID3_LENGHT));
221 snprintf(scroll_text,sizeof(scroll_text), "%d:%02d",
222 id3->length / 60000,
223 id3->length % 60000 / 1000 );
224 lcd_puts(0, 1, scroll_text);
225 break;
227 case 7:
228 lcd_puts(0, 0, str(LANG_ID3_PLAYLIST));
229 snprintf(scroll_text,sizeof(scroll_text), "%d/%d",
230 playlist_get_display_index(), playlist_amount());
231 lcd_puts_scroll(0, 1, scroll_text);
232 break;
235 case 8:
236 lcd_puts(0, 0, str(LANG_ID3_BITRATE));
237 snprintf(scroll_text,sizeof(scroll_text), "%d kbps",
238 id3->bitrate);
239 lcd_puts(0, 1, scroll_text);
240 break;
242 case 9:
243 lcd_puts(0, 0, str(LANG_ID3_FRECUENCY));
244 snprintf(scroll_text,sizeof(scroll_text), "%d Hz",
245 id3->frequency);
246 lcd_puts(0, 1, scroll_text);
247 break;
249 case 10:
250 lcd_puts(0, 0, str(LANG_ID3_PATH));
251 lcd_puts_scroll(0, 1, id3->path);
252 break;
254 lcd_update();
256 button = button_get(true);
258 switch(button)
260 case BUTTON_LEFT:
261 #ifdef HAVE_RECORDER_KEYPAD
262 case BUTTON_UP:
263 #endif
264 if (menu_pos > 0)
265 menu_pos--;
266 else
267 menu_pos = menu_max;
268 break;
270 case BUTTON_RIGHT:
271 #ifdef HAVE_RECORDER_KEYPAD
272 case BUTTON_DOWN:
273 #endif
274 if (menu_pos < menu_max)
275 menu_pos++;
276 else
277 menu_pos = 0;
278 break;
280 case BUTTON_REPEAT:
281 break;
283 #ifdef BUTTON_STOP
284 case BUTTON_STOP:
285 #else
286 case BUTTON_OFF:
287 #endif
288 case BUTTON_PLAY:
289 lcd_stop_scroll();
290 /* eat release event */
291 button_get(true);
292 exit = true;
293 break;
295 case SYS_USB_CONNECTED:
296 status_set_playmode(STATUS_STOP);
297 usb_screen();
298 return true;
299 break;
302 return false;
305 static bool ffwd_rew(int button)
307 static int ff_rew_steps[] = {
308 1000, 2000, 3000, 4000,
309 5000, 6000, 8000, 10000,
310 15000, 20000, 25000, 30000,
311 45000, 60000
314 unsigned int step = 0; /* current ff/rewind step */
315 unsigned int max_step = 0; /* maximum ff/rewind step */
316 int ff_rewind_count = 0; /* current ff/rewind count (in ticks) */
317 int direction = 1; /* forward=1 or backward=-1 */
318 long accel_tick = 0; /* next time at which to bump the step size */
319 bool exit = false;
320 bool usb = false;
322 while (!exit) {
323 switch ( button ) {
324 case BUTTON_LEFT | BUTTON_REPEAT:
325 case BUTTON_RIGHT | BUTTON_REPEAT:
326 if (ff_rewind)
328 ff_rewind_count += step * direction;
330 if (global_settings.ff_rewind_accel != 0 &&
331 current_tick >= accel_tick)
333 step *= 2;
334 if (step > max_step)
335 step = max_step;
337 accel_tick = current_tick +
338 global_settings.ff_rewind_accel*HZ;
341 else
343 if ( (mpeg_status() & MPEG_STATUS_PLAY) &&
344 id3 && id3->length )
346 if (!paused)
347 mpeg_pause();
348 #ifdef HAVE_PLAYER_KEYPAD
349 lcd_stop_scroll();
350 #endif
351 direction = (button & BUTTON_RIGHT) ? 1 : -1;
353 if (direction > 0)
354 status_set_playmode(STATUS_FASTFORWARD);
355 else
356 status_set_playmode(STATUS_FASTBACKWARD);
358 ff_rewind = true;
360 step = ff_rew_steps[global_settings.ff_rewind_min_step];
362 max_step = id3->length * FF_REWIND_MAX_PERCENT / 100;
364 if (step > max_step)
365 step = max_step;
367 ff_rewind_count = step * direction;
368 accel_tick = current_tick +
369 global_settings.ff_rewind_accel*HZ;
371 else
372 break;
375 if (direction > 0) {
376 if ((id3->elapsed + ff_rewind_count) > id3->length)
377 ff_rewind_count = id3->length - id3->elapsed;
379 else {
380 if ((int)(id3->elapsed + ff_rewind_count) < 0)
381 ff_rewind_count = -id3->elapsed;
384 if(wps_time_countup == false)
385 wps_refresh(id3, -ff_rewind_count,
386 WPS_REFRESH_PLAYER_PROGRESS |
387 WPS_REFRESH_DYNAMIC);
388 else
389 wps_refresh(id3, ff_rewind_count,
390 WPS_REFRESH_PLAYER_PROGRESS |
391 WPS_REFRESH_DYNAMIC);
393 break;
395 case BUTTON_LEFT | BUTTON_REL:
396 case BUTTON_RIGHT | BUTTON_REL:
397 mpeg_ff_rewind(id3->elapsed+ff_rewind_count);
398 ff_rewind_count = 0;
399 ff_rewind = false;
400 if (paused)
401 status_set_playmode(STATUS_PAUSE);
402 else {
403 mpeg_resume();
404 status_set_playmode(STATUS_PLAY);
406 #ifdef HAVE_LCD_CHARCELLS
407 wps_display(id3);
408 #endif
409 exit = true;
410 break;
412 case SYS_USB_CONNECTED:
413 status_set_playmode(STATUS_STOP);
414 usb_screen();
415 usb = true;
416 exit = true;
417 break;
419 if (!exit)
420 button = button_get(true);
423 /* let mpeg thread update id3->elapsed before calling wps_refresh */
424 yield();
425 wps_refresh(id3, 0, WPS_REFRESH_ALL);
426 return usb;
429 static bool update(void)
431 bool track_changed = mpeg_has_changed_track();
432 bool retcode = false;
434 if (track_changed)
436 lcd_stop_scroll();
437 id3 = mpeg_current_track();
438 if (wps_display(id3))
439 retcode = true;
440 else
441 wps_refresh(id3, 0, WPS_REFRESH_ALL);
443 if (id3)
444 memcpy(current_track_path, id3->path, sizeof(current_track_path));
447 if (id3)
448 wps_refresh(id3, 0, WPS_REFRESH_NON_STATIC);
450 status_draw(false);
452 /* save resume data */
453 if ( id3 &&
454 global_settings.resume &&
455 global_settings.resume_offset != id3->offset ) {
456 DEBUGF("R%X,%X (%X)\n", global_settings.resume_offset,
457 id3->offset,id3);
459 if (!playlist_get_resume_info(&global_settings.resume_index))
461 global_settings.resume_offset = id3->offset;
462 settings_save();
465 else if ( !id3 && track_changed ) {
466 global_settings.resume_index = -1;
467 global_settings.resume_offset = -1;
468 settings_save();
471 return retcode;
474 static bool menu(void)
476 static bool muted = false;
477 bool exit = false;
478 int last_button = 0;
480 #ifdef HAVE_LCD_CHARCELLS
481 status_set_param(true);
482 status_draw(false);
483 #endif
485 while (!exit) {
486 int button = button_get(true);
488 switch ( button ) {
489 /* go into menu */
490 #ifdef HAVE_RECORDER_KEYPAD
491 case BUTTON_F1 | BUTTON_REL:
492 #else
493 case BUTTON_MENU | BUTTON_REL:
494 #endif
495 exit = true;
496 if ( !last_button && !keys_locked ) {
497 lcd_stop_scroll();
499 if (main_menu())
500 return true;
501 #ifdef HAVE_LCD_BITMAP
502 if(global_settings.statusbar)
503 lcd_setmargins(0, STATUSBAR_HEIGHT);
504 else
505 lcd_setmargins(0, 0);
506 #endif
508 break;
510 /* mute */
511 #ifdef BUTTON_MENU
512 case BUTTON_MENU | BUTTON_PLAY:
513 #else
514 case BUTTON_F1 | BUTTON_PLAY:
515 #endif
516 if ( muted )
517 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
518 else
519 mpeg_sound_set(SOUND_VOLUME, 0);
520 muted = !muted;
521 #ifdef HAVE_LCD_CHARCELLS
522 status_set_param(false);
523 #endif
524 display_mute_text(muted);
525 break;
527 /* key lock */
528 #ifdef HAVE_RECORDER_KEYPAD
529 case BUTTON_F1 | BUTTON_DOWN:
530 #else
531 case BUTTON_MENU | BUTTON_STOP:
532 #endif
533 keys_locked = !keys_locked;
534 display_keylock_text(keys_locked);
535 exit = true;
536 while (button_get(false)); /* clear button queue */
537 break;
539 #ifdef BUTTON_MENU
540 /* change volume */
541 case BUTTON_MENU | BUTTON_LEFT:
542 case BUTTON_MENU | BUTTON_LEFT | BUTTON_REPEAT:
543 case BUTTON_MENU | BUTTON_RIGHT:
544 case BUTTON_MENU | BUTTON_RIGHT | BUTTON_REPEAT:
545 player_change_volume(button);
546 exit = true;
547 break;
549 /* show id3 tags */
550 #ifdef BUTTON_ON
551 case BUTTON_MENU | BUTTON_ON:
552 status_set_param(true);
553 status_set_audio(true);
554 #endif
555 #else
556 case BUTTON_F1 | BUTTON_ON:
557 #endif
558 lcd_clear_display();
559 lcd_puts(0, 0, str(LANG_ID3_INFO));
560 lcd_puts(0, 1, str(LANG_ID3_SCREEN));
561 lcd_update();
562 sleep(HZ);
564 if(browse_id3())
565 return true;
566 #ifdef HAVE_PLAYER_KEYPAD
567 status_set_param(false);
568 status_set_audio(true);
569 #endif
570 exit = true;
571 break;
573 case SYS_USB_CONNECTED:
574 status_set_playmode(STATUS_STOP);
575 usb_screen();
576 return true;
578 last_button = button;
581 #ifdef HAVE_LCD_CHARCELLS
582 status_set_param(false);
583 #endif
585 return false;
588 static void fade(bool fade_in)
590 if (fade_in) {
591 /* fade in */
592 int current_volume = 20;
594 /* zero out the sound */
595 mpeg_sound_set(SOUND_VOLUME, current_volume);
597 sleep(HZ/10); /* let mpeg thread run */
598 mpeg_resume();
600 while (current_volume < global_settings.volume) {
601 current_volume += 2;
602 sleep(1);
603 mpeg_sound_set(SOUND_VOLUME, current_volume);
605 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
607 else {
608 /* fade out */
609 int current_volume = global_settings.volume;
611 while (current_volume > 20) {
612 current_volume -= 2;
613 sleep(1);
614 mpeg_sound_set(SOUND_VOLUME, current_volume);
616 mpeg_pause();
617 sleep(HZ/5); /* let mpeg thread run */
619 /* reset volume to what it was before the fade */
620 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
625 /* demonstrates showing different formats from playtune */
626 int wps_show(void)
628 int button = 0, lastbutton = 0;
629 bool ignore_keyup = true;
630 bool restore = false;
631 bool exit = false;
632 bool update_track = false;
634 id3 = NULL;
635 current_track_path[0] = '\0';
637 #ifdef HAVE_LCD_CHARCELLS
638 status_set_audio(true);
639 status_set_param(false);
640 #else
641 if(global_settings.statusbar)
642 lcd_setmargins(0, STATUSBAR_HEIGHT);
643 else
644 lcd_setmargins(0, 0);
645 #endif
647 ff_rewind = false;
649 if(mpeg_status() & MPEG_STATUS_PLAY)
651 id3 = mpeg_current_track();
652 if (id3) {
653 if (wps_display(id3))
654 return 0;
655 wps_refresh(id3, 0, WPS_REFRESH_ALL);
657 memcpy(current_track_path, id3->path, sizeof(current_track_path));
660 restore = true;
663 while ( 1 )
665 bool mpeg_paused = (mpeg_status() & MPEG_STATUS_PAUSE)?true:false;
667 /* did someone else (i.e power thread) change mpeg pause mode? */
668 if (paused != mpeg_paused) {
669 paused = mpeg_paused;
670 status_set_playmode(paused ? STATUS_PAUSE : STATUS_PLAY);
672 /* if another thread paused mpeg, we are probably in car mode,
673 about to shut down. lets save the settings. */
674 if (paused && global_settings.resume) {
675 settings_save();
676 #ifndef HAVE_RTC
677 ata_flush();
678 #endif
682 #ifdef HAVE_LCD_BITMAP
683 /* when the peak meter is enabled we want to have a
684 few extra updates to make it look smooth. On the
685 other hand we don't want to waste energy if it
686 isn't displayed */
687 if (peak_meter_enabled) {
688 int i;
690 /* In high performance mode we read out the mas as
691 often as we can. There is no sleep for cpu */
692 if (global_settings.peak_meter_performance) {
693 long next_refresh = current_tick;
694 long next_big_refresh = current_tick + HZ / 5;
695 button = BUTTON_NONE;
696 while (!TIME_AFTER(current_tick, next_big_refresh)) {
697 button = button_get(false);
698 if (button != BUTTON_NONE) {
699 break;
701 peak_meter_peek();
702 sleep(1);
704 if (TIME_AFTER(current_tick, next_refresh)) {
705 wps_refresh(id3, 0, WPS_REFRESH_PEAK_METER);
706 next_refresh = current_tick + HZ / peak_meter_fps;
711 /* In energy saver mode the cpu may sleep a
712 little bit while waiting for buttons */
713 else {
714 for (i = 0; i < 4; i++) {
715 button = button_get_w_tmo(HZ / peak_meter_fps);
716 if (button != 0) {
717 break;
719 wps_refresh(id3, 0, WPS_REFRESH_PEAK_METER);
724 /* The peak meter is disabled
725 -> no additional screen updates needed */
726 else {
727 button = button_get_w_tmo(HZ/5);
729 #else
730 button = button_get_w_tmo(HZ/5);
731 #endif
733 /* discard first event if it's a button release */
734 if (button && ignore_keyup)
736 ignore_keyup = false;
737 if (button & BUTTON_REL && button != SYS_USB_CONNECTED)
738 continue;
741 /* ignore non-remote buttons when keys are locked */
742 if (keys_locked &&
743 #ifdef HAVE_RECORDER_KEYPAD
744 ! ((button & BUTTON_F1) ||
745 #else
746 ! ((button & BUTTON_MENU) ||
747 #endif
748 (button == BUTTON_NONE) ||
749 (button == SYS_USB_CONNECTED)
750 #ifdef BUTTON_REMOTE
751 || (button & BUTTON_REMOTE)
752 #endif
755 while (button_get(false)); /* clear button queue */
756 display_keylock_text(true);
757 restore = true;
758 continue;
761 /* Exit if mpeg has stopped playing. This can happen if using the
762 sleep timer with the charger plugged or if starting a recording
763 from F1 */
764 if (!mpeg_status())
765 exit = true;
767 switch(button)
769 #ifdef BUTTON_ON
770 case BUTTON_ON:
771 #ifdef HAVE_RECORDER_KEYPAD
772 switch (on_screen()) {
773 case 2:
774 /* usb connected? */
775 return SYS_USB_CONNECTED;
777 case 1:
778 /* was on_screen used? */
779 restore = true;
781 /* pause may have been turned off by pitch screen */
782 if (paused && !(mpeg_status() & MPEG_STATUS_PAUSE)) {
783 paused = false;
784 status_set_playmode(STATUS_PLAY);
786 break;
788 case 0:
789 /* otherwise, exit to browser */
790 #else
791 status_set_record(false);
792 status_set_audio(false);
793 #endif
794 lcd_stop_scroll();
796 /* set dir browser to current playing song */
797 if (global_settings.browse_current &&
798 current_track_path[0] != '\0')
799 set_current_file(current_track_path);
801 return 0;
802 #ifdef HAVE_RECORDER_KEYPAD
804 break;
805 #endif
806 #endif /* BUTTON_ON */
807 /* play/pause */
808 case BUTTON_PLAY:
809 #ifdef BUTTON_RC_PLAY
810 case BUTTON_RC_PLAY:
811 #endif
812 if ( paused )
814 paused = false;
815 status_set_playmode(STATUS_PLAY);
816 if ( global_settings.fade_on_stop )
817 fade(1);
818 else
819 mpeg_resume();
821 else
823 paused = true;
824 status_set_playmode(STATUS_PAUSE);
825 if ( global_settings.fade_on_stop )
826 fade(0);
827 else
828 mpeg_pause();
829 if (global_settings.resume) {
830 settings_save();
831 #ifndef HAVE_RTC
832 ata_flush();
833 #endif
836 break;
838 /* volume up */
839 #ifdef HAVE_RECORDER_KEYPAD
840 case BUTTON_UP:
841 case BUTTON_UP | BUTTON_REPEAT:
842 #endif
843 #ifdef BUTTON_RC_VOL_UP
844 case BUTTON_RC_VOL_UP:
845 #endif
846 global_settings.volume++;
847 if(global_settings.volume > mpeg_sound_max(SOUND_VOLUME))
848 global_settings.volume = mpeg_sound_max(SOUND_VOLUME);
849 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
850 status_draw(false);
851 settings_save();
852 break;
854 /* volume down */
855 #ifdef HAVE_RECORDER_KEYPAD
856 case BUTTON_DOWN:
857 case BUTTON_DOWN | BUTTON_REPEAT:
858 #endif
859 #ifdef BUTTON_RC_VOL_DOWN
860 case BUTTON_RC_VOL_DOWN:
861 #endif
862 global_settings.volume--;
863 if(global_settings.volume < mpeg_sound_min(SOUND_VOLUME))
864 global_settings.volume = mpeg_sound_min(SOUND_VOLUME);
865 mpeg_sound_set(SOUND_VOLUME, global_settings.volume);
866 status_draw(false);
867 settings_save();
868 break;
870 /* fast forward / rewind */
871 case BUTTON_LEFT | BUTTON_REPEAT:
872 case BUTTON_RIGHT | BUTTON_REPEAT:
873 ffwd_rew(button);
874 break;
876 /* prev / restart */
877 #ifdef BUTTON_RC_LEFT
878 case BUTTON_RC_LEFT:
879 #endif
880 case BUTTON_LEFT | BUTTON_REL:
881 #ifdef HAVE_RECORDER_KEYPAD
882 if ((button == (BUTTON_LEFT | BUTTON_REL)) &&
883 (lastbutton != BUTTON_LEFT ))
884 break;
885 #endif
886 if (!id3 || (id3->elapsed < 3*1000)) {
887 mpeg_prev();
889 else {
890 if (!paused)
891 mpeg_pause();
893 mpeg_ff_rewind(0);
895 if (!paused)
896 mpeg_resume();
898 break;
900 /* next */
901 #ifdef BUTTON_RC_RIGHT
902 case BUTTON_RC_RIGHT:
903 #endif
904 case BUTTON_RIGHT | BUTTON_REL:
905 #ifdef HAVE_RECORDER_KEYPAD
906 if ((button == (BUTTON_RIGHT | BUTTON_REL)) &&
907 (lastbutton != BUTTON_RIGHT))
908 break;
909 #endif
910 mpeg_next();
911 break;
913 /* menu key functions */
914 #ifdef BUTTON_MENU
915 case BUTTON_MENU:
916 #else
917 case BUTTON_F1:
918 #endif
919 if (menu())
920 return SYS_USB_CONNECTED;
922 update_track = true;
923 restore = true;
924 break;
926 #ifdef HAVE_RECORDER_KEYPAD
927 /* play settings */
928 case BUTTON_F2:
929 if (f2_screen())
930 return SYS_USB_CONNECTED;
931 restore = true;
932 break;
934 /* screen settings */
935 case BUTTON_F3:
936 if (f3_screen())
937 return SYS_USB_CONNECTED;
938 restore = true;
939 break;
940 #endif
942 /* stop and exit wps */
943 #ifdef BUTTON_RC_STOP
944 case BUTTON_RC_STOP:
945 #endif
946 #ifdef BUTTON_OFF
947 case BUTTON_OFF | BUTTON_REL:
948 #else
949 case BUTTON_STOP | BUTTON_REL:
950 if ( lastbutton != BUTTON_STOP )
951 break;
952 #endif
953 exit = true;
954 break;
956 case SYS_USB_CONNECTED:
957 status_set_playmode(STATUS_STOP);
958 usb_screen();
959 return SYS_USB_CONNECTED;
961 case BUTTON_NONE: /* Timeout */
962 update_track = true;
963 break;
966 if (update_track)
968 if (update())
970 /* set dir browser to current playing song */
971 if (global_settings.browse_current &&
972 current_track_path[0] != '\0')
973 set_current_file(current_track_path);
975 return 0;
977 update_track = false;
980 if (exit) {
981 #ifdef HAVE_LCD_CHARCELLS
982 status_set_record(false);
983 status_set_audio(false);
984 #endif
985 if (global_settings.fade_on_stop)
986 fade(0);
988 lcd_stop_scroll();
989 bookmark_autobookmark();
990 mpeg_stop();
991 status_set_playmode(STATUS_STOP);
993 /* Keys can be locked when exiting, so either unlock here
994 or implement key locking in tree.c too */
995 keys_locked=false;
997 /* set dir browser to current playing song */
998 if (global_settings.browse_current &&
999 current_track_path[0] != '\0')
1000 set_current_file(current_track_path);
1002 return 0;
1005 if ( button )
1006 ata_spin();
1008 if (restore) {
1009 restore = false;
1010 if (wps_display(id3))
1012 /* set dir browser to current playing song */
1013 if (global_settings.browse_current &&
1014 current_track_path[0] != '\0')
1015 set_current_file(current_track_path);
1017 return 0;
1020 if (id3)
1021 wps_refresh(id3, 0, WPS_REFRESH_NON_STATIC);
1023 if(button != BUTTON_NONE)
1024 lastbutton = button;
1026 return 0; /* unreachable - just to reduce compiler warnings */