1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002-2007 Björn Stenberg
11 * Copyright (C) 2007-2008 Nicolas Pennequin
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
24 #include "string-extra.h"
29 #include "settings_list.h"
30 #include "rbunicode.h"
31 #include "timefuncs.h"
34 #include "powermgmt.h"
37 #ifdef HAVE_LCD_CHARCELLS
44 #ifdef HAVE_LCD_BITMAP
50 #if CONFIG_CODEC == SWCODEC
56 #include "wps_internals.h"
57 #include "root_menu.h"
59 #include "recording.h"
60 #include "pcm_record.h"
69 extern struct wps_state wps_state
;
71 static const char* get_codectype(const struct mp3entry
* id3
)
73 if (id3
&& id3
->codectype
< AFMT_NUM_CODECS
) {
74 return audio_formats
[id3
->codectype
].label
;
80 /* Extract a part from a path.
82 * buf - buffer extract part to.
83 * buf_size - size of buffer.
84 * path - path to extract from.
85 * level - what to extract. 0 is file name, 1 is parent of file, 2 is
86 * parent of parent, etc.
88 * Returns buf if the desired level was found, NULL otherwise.
90 char* get_dir(char* buf
, int buf_size
, const char* path
, int level
)
96 sep
= path
+ strlen(path
);
111 if (level
|| (last_sep
<= sep
))
114 len
= MIN(last_sep
- sep
, buf_size
- 1);
115 strlcpy(buf
, sep
+ 1, len
+ 1);
119 #if (CONFIG_CODEC != MAS3507D)
120 /* A helper to determine the enum value for pitch/speed.
122 When there are two choices (i.e. boolean), return 1 if the value is
123 different from normal value and 2 if the value is the same as the
124 normal value. E.g. "%?Sp<%Sp>" would show the pitch only when
125 playing at a modified pitch.
127 When there are more than two choices (i.e. enum), the left half of
128 the choices are to show 0..normal range, and the right half of the
129 choices are to show values over that. The last entry is used when
130 it is set to the normal setting, following the rockbox convention
131 to use the last entry for special values.
135 2 items: %?Sp<0..99 or 101..infinity|100>
136 3 items: %?Sp<0..99|101..infinity|100>
137 4 items: %?Sp<0..49|50..99|101..infinity|100>
138 5 items: %?Sp<0..49|50..99|101..149|150..infinity|100>
139 6 items: %?Sp<0..33|34..66|67..99|101..133|134..infinity|100>
140 7 items: %?Sp<0..33|34..66|67..99|101..133|134..167|167..infinity|100>
142 static int pitch_speed_enum(int range
, int32_t val
, int32_t normval
)
148 return (val
== normval
) + 1;
152 n
= (center
* val
) / normval
+ 1;
153 return (range
<= n
) ? (range
- 1) : n
;
158 /* All tokens which only need the info to return a value go in here */
159 const char *get_id3_token(struct wps_token
*token
, struct mp3entry
*id3
,
160 char *buf
, int buf_size
, int limit
, int *intval
)
162 struct wps_state
*state
= &wps_state
;
165 unsigned long length
= id3
->length
;
166 unsigned long elapsed
= id3
->elapsed
+ state
->ff_rewind_count
;
169 case WPS_TOKEN_METADATA_ARTIST
:
171 case WPS_TOKEN_METADATA_COMPOSER
:
172 return id3
->composer
;
173 case WPS_TOKEN_METADATA_ALBUM
:
175 case WPS_TOKEN_METADATA_ALBUM_ARTIST
:
176 return id3
->albumartist
;
177 case WPS_TOKEN_METADATA_GROUPING
:
178 return id3
->grouping
;
179 case WPS_TOKEN_METADATA_GENRE
:
180 return id3
->genre_string
;
181 case WPS_TOKEN_METADATA_DISC_NUMBER
:
182 if (id3
->disc_string
)
183 return id3
->disc_string
;
185 snprintf(buf
, buf_size
, "%d", id3
->discnum
);
189 case WPS_TOKEN_METADATA_TRACK_NUMBER
:
190 if (id3
->track_string
)
191 return id3
->track_string
;
193 snprintf(buf
, buf_size
, "%d", id3
->tracknum
);
197 case WPS_TOKEN_METADATA_TRACK_TITLE
:
199 case WPS_TOKEN_METADATA_VERSION
:
200 switch (id3
->id3version
)
216 case WPS_TOKEN_METADATA_YEAR
:
217 if( id3
->year_string
)
218 return id3
->year_string
;
220 snprintf(buf
, buf_size
, "%d", id3
->year
);
224 case WPS_TOKEN_METADATA_COMMENT
:
226 case WPS_TOKEN_FILE_PATH
:
228 case WPS_TOKEN_FILE_BITRATE
:
230 snprintf(buf
, buf_size
, "%d", id3
->bitrate
);
234 case WPS_TOKEN_TRACK_TIME_ELAPSED
:
235 format_time(buf
, buf_size
, elapsed
);
238 case WPS_TOKEN_TRACK_TIME_REMAINING
:
239 format_time(buf
, buf_size
, length
- elapsed
);
242 case WPS_TOKEN_TRACK_LENGTH
:
243 format_time(buf
, buf_size
, length
);
246 case WPS_TOKEN_TRACK_ELAPSED_PERCENT
:
252 *intval
= limit
* elapsed
/ length
+ 1;
254 snprintf(buf
, buf_size
, "%lu", 100 * elapsed
/ length
);
258 case WPS_TOKEN_FILE_CODEC
:
261 if(id3
->codectype
== AFMT_UNKNOWN
)
262 *intval
= AFMT_NUM_CODECS
;
264 *intval
= id3
->codectype
;
266 return get_codectype(id3
);
268 case WPS_TOKEN_FILE_FREQUENCY
:
269 snprintf(buf
, buf_size
, "%ld", id3
->frequency
);
271 case WPS_TOKEN_FILE_FREQUENCY_KHZ
:
272 /* ignore remainders < 100, so 22050 Hz becomes just 22k */
273 if ((id3
->frequency
% 1000) < 100)
274 snprintf(buf
, buf_size
, "%ld", id3
->frequency
/ 1000);
276 snprintf(buf
, buf_size
, "%ld.%lu",
277 id3
->frequency
/ 1000,
278 (id3
->frequency
% 1000) / 100);
280 case WPS_TOKEN_FILE_NAME
:
281 if (get_dir(buf
, buf_size
, id3
->path
, 0)) {
282 /* Remove extension */
283 char* sep
= strrchr(buf
, '.');
290 case WPS_TOKEN_FILE_NAME_WITH_EXTENSION
:
291 return get_dir(buf
, buf_size
, id3
->path
, 0);
292 case WPS_TOKEN_FILE_SIZE
:
293 snprintf(buf
, buf_size
, "%ld", id3
->filesize
/ 1024);
295 case WPS_TOKEN_FILE_VBR
:
296 return (id3
->vbr
) ? "(avg)" : NULL
;
297 case WPS_TOKEN_FILE_DIRECTORY
:
298 return get_dir(buf
, buf_size
, id3
->path
, token
->value
.i
);
301 case WPS_TOKEN_DATABASE_PLAYCOUNT
:
303 *intval
= id3
->playcount
+ 1;
304 snprintf(buf
, buf_size
, "%ld", id3
->playcount
);
306 case WPS_TOKEN_DATABASE_RATING
:
308 *intval
= id3
->rating
+ 1;
309 snprintf(buf
, buf_size
, "%d", id3
->rating
);
311 case WPS_TOKEN_DATABASE_AUTOSCORE
:
313 *intval
= id3
->score
+ 1;
314 snprintf(buf
, buf_size
, "%d", id3
->score
);
322 else /* id3 == NULL, handle the error based on the expected return type */
326 /* Most tokens expect NULL on error so leave that for the default case,
327 * The ones that expect "0" need to be handled */
328 case WPS_TOKEN_FILE_FREQUENCY
:
329 case WPS_TOKEN_FILE_FREQUENCY_KHZ
:
330 case WPS_TOKEN_FILE_SIZE
:
332 case WPS_TOKEN_DATABASE_PLAYCOUNT
:
333 case WPS_TOKEN_DATABASE_RATING
:
334 case WPS_TOKEN_DATABASE_AUTOSCORE
:
348 /* Formats the frequency (specified in Hz) in MHz, */
349 /* with two digits after the decimal point */
350 static void format_freq_MHz(int freq
, char *buf
, int buf_size
)
353 snprintf(buf
, buf_size
, "%d.%02d", freq
/100, freq
%100);
357 /* Tokens which are really only used by the radio screen go in here */
358 const char *get_radio_token(struct wps_token
*token
, int preset_offset
,
359 char *buf
, int buf_size
, int limit
, int *intval
)
364 /* Radio/tuner tokens */
365 case WPS_TOKEN_TUNER_TUNED
:
366 if (tuner_get(RADIO_TUNED
))
369 case WPS_TOKEN_TUNER_SCANMODE
:
370 if (radio_scan_mode())
373 case WPS_TOKEN_TUNER_STEREO
:
374 if (radio_is_stereo())
377 case WPS_TOKEN_TUNER_MINFREQ
: /* changes based on "region" */
379 format_freq_MHz(fm_region_data
[global_settings
.fm_region
].freq_min
,
383 case WPS_TOKEN_TUNER_MAXFREQ
: /* changes based on "region" */
385 format_freq_MHz(fm_region_data
[global_settings
.fm_region
].freq_max
,
389 case WPS_TOKEN_TUNER_CURFREQ
:
391 format_freq_MHz(radio_current_frequency(),
395 case WPS_TOKEN_PRESET_ID
:
396 snprintf(buf
, buf_size
, "%d", radio_current_preset() + 1 + preset_offset
);
398 case WPS_TOKEN_PRESET_NAME
:
399 case WPS_TOKEN_PRESET_FREQ
:
401 int preset_count
= radio_preset_count();
402 int cur_preset
= radio_current_preset();
403 if (preset_count
== 0 || cur_preset
< 0)
405 int preset
= cur_preset
+ preset_offset
;
406 /* make sure it's in the valid range */
408 preset
+= preset_count
;
409 preset
%= preset_count
;
410 if (token
->type
== WPS_TOKEN_PRESET_NAME
)
412 snprintf(buf
, buf_size
, "%s", radio_get_preset(preset
)->name
);
416 format_freq_MHz(radio_get_preset(preset
)->frequency
,
421 case WPS_TOKEN_PRESET_COUNT
:
422 snprintf(buf
, buf_size
, "%d", radio_preset_count());
424 *intval
= radio_preset_count();
426 case WPS_TOKEN_HAVE_RDS
:
429 case WPS_TOKEN_RDS_NAME
:
430 return tuner_get_rds_info(RADIO_RDS_NAME
);
431 case WPS_TOKEN_RDS_TEXT
:
432 return tuner_get_rds_info(RADIO_RDS_TEXT
);
434 return NULL
; /* end of the WPS_TOKEN_HAVE_RDS case */
435 #endif /* HAVE_RDS_CAP */
441 /* Return the tags value as text. buf should be used as temp storage if needed.
443 intval is used with conditionals/enums: when this function is called,
444 intval should contain the number of options in the conditional/enum.
445 When this function returns, intval is -1 if the tag is non numeric or,
446 if the tag is numeric, *intval is the enum case we want to go to (between 1
447 and the original value of *intval, inclusive).
448 When not treating a conditional/enum, intval should be NULL.
450 const char *get_token_value(struct gui_wps
*gwps
,
451 struct wps_token
*token
,
452 char *buf
, int buf_size
,
458 struct wps_data
*data
= gwps
->data
;
459 struct wps_state
*state
= gwps
->state
;
460 struct mp3entry
*id3
; /* Think very carefully about using this.
461 maybe get_id3_token() is the better place? */
462 const char *out_text
= NULL
;
474 struct tm
* tm
= NULL
;
476 /* if the token is an RTC one, update the time
477 and do the necessary checks */
478 if (token
->type
>= WPS_TOKENS_RTC_BEGIN
479 && token
->type
<= WPS_TOKENS_RTC_END
)
495 out_text
= get_id3_token(token
, id3
, buf
, buf_size
, limit
, intval
);
499 out_text
= get_radio_token(token
, 0, buf
, buf_size
, limit
, intval
);
506 case WPS_TOKEN_CHARACTER
:
507 if (token
->value
.c
== '\n')
509 return &(token
->value
.c
);
511 case WPS_TOKEN_STRING
:
512 return (char*)token
->value
.data
;
514 case WPS_TOKEN_TRANSLATEDSTRING
:
515 return (char*)P2STR(ID2P(token
->value
.i
));
517 case WPS_TOKEN_PLAYLIST_ENTRIES
:
518 snprintf(buf
, buf_size
, "%d", playlist_amount());
521 case WPS_TOKEN_LIST_TITLE_TEXT
:
522 return (char*)token
->value
.data
;
523 case WPS_TOKEN_LIST_TITLE_ICON
:
525 *intval
= token
->value
.i
;
526 snprintf(buf
, buf_size
, "%d", token
->value
.i
);
529 case WPS_TOKEN_PLAYLIST_NAME
:
530 return playlist_name(NULL
, buf
, buf_size
);
532 case WPS_TOKEN_PLAYLIST_POSITION
:
533 snprintf(buf
, buf_size
, "%d", playlist_get_display_index());
536 case WPS_TOKEN_PLAYLIST_SHUFFLE
:
537 if ( global_settings
.playlist_shuffle
)
543 case WPS_TOKEN_VOLUME
:
544 snprintf(buf
, buf_size
, "%d", global_settings
.volume
);
547 int minvol
= sound_min(SOUND_VOLUME
);
548 if (global_settings
.volume
== minvol
)
552 else if (global_settings
.volume
== 0)
556 else if (global_settings
.volume
> 0)
562 *intval
= (limit
-3) * (global_settings
.volume
- minvol
- 1)
568 case WPS_TOKEN_ALBUMART_FOUND
:
569 if (data
->albumart
) {
570 if (playback_current_aa_hid(data
->playback_aa_slot
) >= 0)
575 case WPS_TOKEN_ALBUMART_DISPLAY
:
578 if (!data
->albumart
->draw
)
579 data
->albumart
->draw
= true;
583 case WPS_TOKEN_BATTERY_PERCENT
:
585 int l
= battery_level();
589 limit
= MAX(limit
, 2);
591 /* First enum is used for "unknown level". */
592 *intval
= (limit
- 1) * l
/ 100 + 2;
599 snprintf(buf
, buf_size
, "%d", l
);
606 case WPS_TOKEN_BATTERY_VOLTS
:
608 unsigned int v
= battery_voltage();
609 snprintf(buf
, buf_size
, "%d.%02d", v
/ 1000, (v
% 1000) / 10);
613 case WPS_TOKEN_BATTERY_TIME
:
615 int t
= battery_time();
617 snprintf(buf
, buf_size
, "%dh %dm", t
/ 60, t
% 60);
624 case WPS_TOKEN_BATTERY_CHARGER_CONNECTED
:
626 if(charger_input_state
==CHARGER
)
632 #if CONFIG_CHARGING >= CHARGING_MONITOR
633 case WPS_TOKEN_BATTERY_CHARGING
:
635 if (charge_state
== CHARGING
|| charge_state
== TOPOFF
) {
642 #ifdef HAVE_USB_POWER
643 case WPS_TOKEN_USB_POWERED
:
648 case WPS_TOKEN_BATTERY_SLEEPTIME
:
650 if (get_sleep_timer() == 0)
654 format_time(buf
, buf_size
, get_sleep_timer() * 1000);
659 case WPS_TOKEN_PLAYBACK_STATUS
:
661 int status
= current_playmode();
663 int mode
= 1; /* stop */
664 if (status
== STATUS_PLAY
)
666 if (state
->is_fading
||
667 (status
== STATUS_PAUSE
&& !status_get_ffmode()))
668 mode
= 3; /* pause */
671 if (status_get_ffmode() == STATUS_FASTFORWARD
)
673 if (status_get_ffmode() == STATUS_FASTBACKWARD
)
676 #ifdef HAVE_RECORDING
678 if (status
== STATUS_RECORD
)
680 else if (status
== STATUS_RECORD_PAUSE
)
685 if (status
== STATUS_RADIO
)
687 else if (status
== STATUS_RADIO_PAUSE
)
695 snprintf(buf
, buf_size
, "%d", mode
-1);
699 case WPS_TOKEN_REPEAT_MODE
:
701 *intval
= global_settings
.repeat_mode
+ 1;
702 snprintf(buf
, buf_size
, "%d", global_settings
.repeat_mode
);
705 case WPS_TOKEN_RTC_PRESENT
:
713 case WPS_TOKEN_RTC_12HOUR_CFG
:
715 *intval
= global_settings
.timeformat
+ 1;
716 snprintf(buf
, buf_size
, "%d", global_settings
.timeformat
);
719 case WPS_TOKEN_RTC_DAY_OF_MONTH
:
720 /* d: day of month (01..31) */
721 snprintf(buf
, buf_size
, "%02d", tm
->tm_mday
);
723 *intval
= tm
->tm_mday
- 1;
726 case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED
:
727 /* e: day of month, blank padded ( 1..31) */
728 snprintf(buf
, buf_size
, "%2d", tm
->tm_mday
);
730 *intval
= tm
->tm_mday
- 1;
733 case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED
:
734 /* H: hour (00..23) */
735 snprintf(buf
, buf_size
, "%02d", tm
->tm_hour
);
737 *intval
= tm
->tm_hour
;
740 case WPS_TOKEN_RTC_HOUR_24
:
741 /* k: hour ( 0..23) */
742 snprintf(buf
, buf_size
, "%2d", tm
->tm_hour
);
744 *intval
= tm
->tm_hour
;
747 case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED
:
748 /* I: hour (01..12) */
749 snprintf(buf
, buf_size
, "%02d",
750 (tm
->tm_hour
% 12 == 0) ? 12 : tm
->tm_hour
% 12);
752 *intval
= (tm
->tm_hour
% 12 == 0) ? 12 : tm
->tm_hour
% 12;
755 case WPS_TOKEN_RTC_HOUR_12
:
756 /* l: hour ( 1..12) */
757 snprintf(buf
, buf_size
, "%2d",
758 (tm
->tm_hour
% 12 == 0) ? 12 : tm
->tm_hour
% 12);
760 *intval
= (tm
->tm_hour
% 12 == 0) ? 12 : tm
->tm_hour
% 12;
763 case WPS_TOKEN_RTC_MONTH
:
764 /* m: month (01..12) */
766 *intval
= tm
->tm_mon
+ 1;
767 snprintf(buf
, buf_size
, "%02d", tm
->tm_mon
+ 1);
770 case WPS_TOKEN_RTC_MINUTE
:
771 /* M: minute (00..59) */
772 snprintf(buf
, buf_size
, "%02d", tm
->tm_min
);
774 *intval
= tm
->tm_min
;
777 case WPS_TOKEN_RTC_SECOND
:
778 /* S: second (00..59) */
779 snprintf(buf
, buf_size
, "%02d", tm
->tm_sec
);
781 *intval
= tm
->tm_sec
;
784 case WPS_TOKEN_RTC_YEAR_2_DIGITS
:
785 /* y: last two digits of year (00..99) */
786 snprintf(buf
, buf_size
, "%02d", tm
->tm_year
% 100);
788 *intval
= tm
->tm_year
% 100;
791 case WPS_TOKEN_RTC_YEAR_4_DIGITS
:
792 /* Y: year (1970...) */
793 snprintf(buf
, buf_size
, "%04d", tm
->tm_year
+ 1900);
795 *intval
= tm
->tm_year
+ 1900;
798 case WPS_TOKEN_RTC_AM_PM_UPPER
:
799 /* p: upper case AM or PM indicator */
801 *intval
= tm
->tm_hour
/12 == 0 ? 0 : 1;
802 return tm
->tm_hour
/12 == 0 ? "AM" : "PM";
804 case WPS_TOKEN_RTC_AM_PM_LOWER
:
805 /* P: lower case am or pm indicator */
807 *intval
= tm
->tm_hour
/12 == 0 ? 0 : 1;
808 return tm
->tm_hour
/12 == 0 ? "am" : "pm";
810 case WPS_TOKEN_RTC_WEEKDAY_NAME
:
811 /* a: abbreviated weekday name (Sun..Sat) */
812 return str(LANG_WEEKDAY_SUNDAY
+ tm
->tm_wday
);
814 case WPS_TOKEN_RTC_MONTH_NAME
:
815 /* b: abbreviated month name (Jan..Dec) */
816 return str(LANG_MONTH_JANUARY
+ tm
->tm_mon
);
818 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON
:
819 /* u: day of week (1..7); 1 is Monday */
821 *intval
= (tm
->tm_wday
== 0) ? 7 : tm
->tm_wday
;
822 snprintf(buf
, buf_size
, "%1d", tm
->tm_wday
+ 1);
825 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN
:
826 /* w: day of week (0..6); 0 is Sunday */
828 *intval
= tm
->tm_wday
+ 1;
829 snprintf(buf
, buf_size
, "%1d", tm
->tm_wday
);
832 case WPS_TOKEN_RTC_DAY_OF_MONTH
:
833 case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED
:
834 case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED
:
835 case WPS_TOKEN_RTC_HOUR_24
:
836 case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED
:
837 case WPS_TOKEN_RTC_HOUR_12
:
838 case WPS_TOKEN_RTC_MONTH
:
839 case WPS_TOKEN_RTC_MINUTE
:
840 case WPS_TOKEN_RTC_SECOND
:
841 case WPS_TOKEN_RTC_AM_PM_UPPER
:
842 case WPS_TOKEN_RTC_AM_PM_LOWER
:
843 case WPS_TOKEN_RTC_YEAR_2_DIGITS
:
845 case WPS_TOKEN_RTC_YEAR_4_DIGITS
:
847 case WPS_TOKEN_RTC_WEEKDAY_NAME
:
848 case WPS_TOKEN_RTC_MONTH_NAME
:
850 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON
:
851 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN
:
855 #ifdef HAVE_LCD_CHARCELLS
856 case WPS_TOKEN_PROGRESSBAR
:
858 char *end
= utf8encode(data
->wps_progress_pat
[0], buf
);
863 case WPS_TOKEN_PLAYER_PROGRESSBAR
:
866 /* we need 11 characters (full line) for
868 strlcpy(buf
, " ", buf_size
);
872 /* Tell the user if we have an OldPlayer */
873 strlcpy(buf
, " <Old LCD> ", buf_size
);
880 #if (CONFIG_CODEC == SWCODEC)
881 case WPS_TOKEN_CROSSFADE
:
882 #ifdef HAVE_CROSSFADE
884 *intval
= global_settings
.crossfade
+ 1;
885 snprintf(buf
, buf_size
, "%d", global_settings
.crossfade
);
887 snprintf(buf
, buf_size
, "%d", 0);
891 case WPS_TOKEN_REPLAYGAIN
:
895 if (global_settings
.replaygain_type
== REPLAYGAIN_OFF
)
901 type
= get_replaygain_mode(id3
->track_gain_string
!= NULL
,
902 id3
->album_gain_string
!= NULL
);
907 val
= 6; /* no tag */
911 if (global_settings
.replaygain_type
== REPLAYGAIN_SHUFFLE
)
924 /* due to above, coming here with !id3 shouldn't be possible */
927 strlcpy(buf
, id3
->track_gain_string
, buf_size
);
931 strlcpy(buf
, id3
->album_gain_string
, buf_size
);
936 #endif /* (CONFIG_CODEC == SWCODEC) */
938 #if (CONFIG_CODEC != MAS3507D)
939 case WPS_TOKEN_SOUND_PITCH
:
941 int32_t pitch
= sound_get_pitch();
942 snprintf(buf
, buf_size
, "%ld.%ld",
943 pitch
/ PITCH_SPEED_PRECISION
,
944 (pitch
% PITCH_SPEED_PRECISION
) / (PITCH_SPEED_PRECISION
/ 10));
947 *intval
= pitch_speed_enum(limit
, pitch
,
948 PITCH_SPEED_PRECISION
* 100);
953 #if CONFIG_CODEC == SWCODEC
954 case WPS_TOKEN_SOUND_SPEED
:
956 int32_t pitch
= sound_get_pitch();
958 if (dsp_timestretch_available())
959 speed
= GET_SPEED(pitch
, dsp_get_timestretch());
962 snprintf(buf
, buf_size
, "%ld.%ld",
963 speed
/ PITCH_SPEED_PRECISION
,
964 (speed
% PITCH_SPEED_PRECISION
) / (PITCH_SPEED_PRECISION
/ 10));
966 *intval
= pitch_speed_enum(limit
, speed
,
967 PITCH_SPEED_PRECISION
* 100);
972 case WPS_TOKEN_MAIN_HOLD
:
973 #ifdef HAS_BUTTON_HOLD
976 if (is_keys_locked())
977 #endif /*hold switch or softlock*/
982 #ifdef HAS_REMOTE_BUTTON_HOLD
983 case WPS_TOKEN_REMOTE_HOLD
:
984 if (remote_button_hold())
990 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
991 case WPS_TOKEN_VLED_HDD
:
997 case WPS_TOKEN_BUTTON_VOLUME
:
998 if (global_status
.last_volume_change
&&
999 TIME_BEFORE(current_tick
, global_status
.last_volume_change
+
1000 token
->value
.i
* TIMEOUT_UNIT
))
1004 case WPS_TOKEN_TRACK_STARTING
:
1007 int elapsed
= id3
->elapsed
+ state
->ff_rewind_count
;
1008 if (elapsed
< token
->value
.i
* 1000)
1012 case WPS_TOKEN_TRACK_ENDING
:
1015 unsigned long elapsed
= id3
->elapsed
+ state
->ff_rewind_count
;
1016 unsigned time
= token
->value
.i
* 1000;
1017 if (id3
->length
- elapsed
< time
)
1021 case WPS_TOKEN_LASTTOUCH
:
1022 #ifdef HAVE_TOUCHSCREEN
1023 if (TIME_BEFORE(current_tick
, token
->value
.i
* TIMEOUT_UNIT
+
1024 touchscreen_last_touch()))
1029 case WPS_TOKEN_SETTING
:
1031 const struct settings_list
*s
= settings
+token
->value
.i
;
1034 /* Handle contionals */
1035 switch (s
->flags
&F_T_MASK
)
1039 if (s
->flags
&F_T_SOUND
)
1041 /* %?St|name|<min|min+1|...|max-1|max> */
1042 int sound_setting
= s
->sound_setting
->setting
;
1043 /* settings with decimals can't be used in conditionals */
1044 if (sound_numdecimals(sound_setting
) == 0)
1046 *intval
= (*(int*)s
->setting
-sound_min(sound_setting
))
1047 /sound_steps(sound_setting
) + 1;
1052 else if (s
->flags
&F_RGB
)
1053 /* %?St|name|<#000000|#000001|...|#FFFFFF> */
1054 /* shouldn't overflow since colors are stored
1056 * but this is pretty useless anyway */
1057 *intval
= *(int*)s
->setting
+ 1;
1058 else if (s
->cfg_vals
== NULL
)
1059 /* %?St|name|<1st choice|2nd choice|...> */
1060 *intval
= (*(int*)s
->setting
-s
->int_setting
->min
)
1061 /s
->int_setting
->step
+ 1;
1063 /* %?St|name|<1st choice|2nd choice|...> */
1064 /* Not sure about this one. cfg_name/vals are
1065 * indexed from 0 right? */
1066 *intval
= *(int*)s
->setting
+ 1;
1069 /* %?St|name|<if true|if false> */
1070 *intval
= *(bool*)s
->setting
?1:2;
1074 /* %?St|name|<if non empty string|if empty>
1075 * The string's emptyness discards the setting's
1076 * prefix and suffix */
1077 *intval
= ((char*)s
->setting
)[0]?1:2;
1078 /* if there is a prefix we should ignore it here */
1079 if (s
->filename_setting
->prefix
)
1080 return (char*)s
->setting
;
1083 /* This shouldn't happen ... but you never know */
1088 /* Special handlng for filenames because we dont want to show the prefix */
1089 if ((s
->flags
&F_T_MASK
) == F_T_UCHARPTR
||
1090 (s
->flags
&F_T_MASK
) == F_T_UCHARPTR
)
1092 if (s
->filename_setting
->prefix
)
1093 return (char*)s
->setting
;
1095 cfg_to_string(token
->value
.i
,buf
,buf_size
);
1098 case WPS_TOKEN_HAVE_TUNER
:
1100 if (radio_hardware_present())
1104 /* Recording tokens */
1105 case WPS_TOKEN_HAVE_RECORDING
:
1106 #ifdef HAVE_RECORDING
1112 #ifdef HAVE_RECORDING
1113 case WPS_TOKEN_IS_RECORDING
:
1114 if (audio_status() == AUDIO_STATUS_RECORD
)
1117 case WPS_TOKEN_REC_FREQ
: /* order from REC_FREQ_CFG_VAL_LIST */
1119 #if CONFIG_CODEC == SWCODEC
1120 unsigned long samprk
;
1121 int rec_freq
= global_settings
.rec_frequency
;
1126 #if defined(HAVE_SPDIF_REC)
1127 if (global_settings
.rec_source
== AUDIO_SRC_SPDIF
)
1129 /* Use rate in use, not current measured rate if it changed */
1130 samprk
= pcm_rec_sample_rate();
1132 while (rec_freq
< SAMPR_NUM_FREQ
&&
1133 audio_master_sampr_list
[rec_freq
] != samprk
)
1140 samprk
= rec_freq_sampr
[rec_freq
];
1141 #endif /* SIMULATOR */
1146 REC_HAVE_96_(case REC_FREQ_96
:
1149 REC_HAVE_88_(case REC_FREQ_88
:
1152 REC_HAVE_64_(case REC_FREQ_64
:
1155 REC_HAVE_48_(case REC_FREQ_48
:
1158 REC_HAVE_44_(case REC_FREQ_44
:
1161 REC_HAVE_32_(case REC_FREQ_32
:
1164 REC_HAVE_24_(case REC_FREQ_24
:
1167 REC_HAVE_22_(case REC_FREQ_22
:
1170 REC_HAVE_16_(case REC_FREQ_16
:
1173 REC_HAVE_12_(case REC_FREQ_12
:
1176 REC_HAVE_11_(case REC_FREQ_11
:
1179 REC_HAVE_8_(case REC_FREQ_8
:
1184 snprintf(buf
, buf_size
, "%lu.%1lu", samprk
/1000,samprk
%1000);
1187 static const char * const freq_strings
[] =
1188 {"--", "44", "48", "32", "22", "24", "16"};
1189 int freq
= 1 + global_settings
.rec_frequency
;
1190 #ifdef HAVE_SPDIF_REC
1191 if (global_settings
.rec_source
== AUDIO_SRC_SPDIF
)
1193 /* Can't measure S/PDIF sample rate on Archos/Sim yet */
1196 #endif /* HAVE_SPDIF_IN */
1198 *intval
= freq
+1; /* so the token gets a value 1<=x<=7 */
1199 snprintf(buf
, buf_size
, "%s\n",
1200 freq_strings
[global_settings
.rec_frequency
]);
1204 #if CONFIG_CODEC == SWCODEC
1205 case WPS_TOKEN_REC_ENCODER
:
1207 int rec_format
= global_settings
.rec_format
+1; /* WAV, AIFF, WV, MPEG */
1209 *intval
= rec_format
;
1212 case REC_FORMAT_PCM_WAV
:
1214 case REC_FORMAT_AIFF
:
1216 case REC_FORMAT_WAVPACK
:
1218 case REC_FORMAT_MPA_L3
:
1226 case WPS_TOKEN_REC_BITRATE
:
1227 #if CONFIG_CODEC == SWCODEC
1228 if (global_settings
.rec_format
== REC_FORMAT_MPA_L3
)
1232 #if 0 /* FIXME: I dont know if this is needed? */
1233 switch (1<<global_settings
.mp3_enc_config
.bitrate
)
1235 case MP3_BITR_CAP_8
:
1238 case MP3_BITR_CAP_16
:
1241 case MP3_BITR_CAP_24
:
1244 case MP3_BITR_CAP_32
:
1247 case MP3_BITR_CAP_40
:
1250 case MP3_BITR_CAP_48
:
1253 case MP3_BITR_CAP_56
:
1256 case MP3_BITR_CAP_64
:
1259 case MP3_BITR_CAP_80
:
1262 case MP3_BITR_CAP_96
:
1265 case MP3_BITR_CAP_112
:
1268 case MP3_BITR_CAP_128
:
1271 case MP3_BITR_CAP_144
:
1274 case MP3_BITR_CAP_160
:
1277 case MP3_BITR_CAP_192
:
1282 *intval
= global_settings
.mp3_enc_config
.bitrate
+1;
1284 snprintf(buf
, buf_size
, "%lu", global_settings
.mp3_enc_config
.bitrate
+1);
1288 return NULL
; /* Fixme later */
1289 #else /* CONFIG_CODEC == HWCODEC */
1291 *intval
= global_settings
.rec_quality
+1;
1292 snprintf(buf
, buf_size
, "%d", global_settings
.rec_quality
);
1295 case WPS_TOKEN_REC_MONO
:
1296 if (!global_settings
.rec_channels
)
1300 case WPS_TOKEN_REC_SECONDS
:
1302 int time
= (audio_recorded_time() / HZ
) % 60;
1305 snprintf(buf
, buf_size
, "%02d", time
);
1308 case WPS_TOKEN_REC_MINUTES
:
1310 int time
= (audio_recorded_time() / HZ
) / 60;
1313 snprintf(buf
, buf_size
, "%02d", time
);
1316 case WPS_TOKEN_REC_HOURS
:
1318 int time
= (audio_recorded_time() / HZ
) / 3600;
1321 snprintf(buf
, buf_size
, "%02d", time
);
1325 #endif /* HAVE_RECORDING */
1327 case WPS_TOKEN_CURRENT_SCREEN
:
1329 int curr_screen
= current_screen();
1331 #ifdef HAVE_RECORDING
1332 /* override current_screen() for recording screen since it may
1333 * be entered from the radio screen */
1334 if (in_recording_screen())
1335 curr_screen
= GO_TO_RECSCREEN
;
1338 switch (curr_screen
)
1343 #ifdef HAVE_RECORDING
1344 case GO_TO_RECSCREEN
:
1353 case GO_TO_PLAYLIST_VIEWER
:
1356 default: /* lists */
1362 *intval
= curr_screen
;
1364 snprintf(buf
, buf_size
, "%d", curr_screen
);
1368 case WPS_TOKEN_LANG_IS_RTL
:
1369 return lang_is_rtl() ? "r" : NULL
;