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
:
347 /* Tokens which are really only used by the radio screen go in here */
348 const char *get_radio_token(struct wps_token
*token
, int preset_offset
,
349 char *buf
, int buf_size
, int limit
, int *intval
)
354 /* Radio/tuner tokens */
355 case WPS_TOKEN_TUNER_TUNED
:
356 if (tuner_get(RADIO_TUNED
))
359 case WPS_TOKEN_TUNER_SCANMODE
:
360 if (radio_scan_mode())
363 case WPS_TOKEN_TUNER_STEREO
:
364 if (radio_is_stereo())
367 case WPS_TOKEN_TUNER_MINFREQ
: /* changes based on "region" */
369 int freq
= fm_region_data
[global_settings
.fm_region
].freq_min
/ 10000;
370 snprintf(buf
, buf_size
, "%d.%02d", freq
/100, freq
%100);
373 case WPS_TOKEN_TUNER_MAXFREQ
: /* changes based on "region" */
375 int freq
= fm_region_data
[global_settings
.fm_region
].freq_max
/ 10000;
376 snprintf(buf
, buf_size
, "%d.%02d", freq
/100, freq
%100);
379 case WPS_TOKEN_TUNER_CURFREQ
:
381 int freq
= radio_current_frequency() / 10000;
382 snprintf(buf
, buf_size
, "%d.%02d", freq
/100, freq
%100);
385 case WPS_TOKEN_PRESET_ID
:
386 snprintf(buf
, buf_size
, "%d", radio_current_preset() + 1 + preset_offset
);
388 case WPS_TOKEN_PRESET_NAME
:
389 case WPS_TOKEN_PRESET_FREQ
:
391 int preset
= radio_current_preset() + preset_offset
;
392 if (radio_preset_count() == 0 || preset
== -1)
394 /* make sure its in the valid range */
396 preset
+= radio_preset_count();
397 preset
%= radio_preset_count();
398 if (token
->type
== WPS_TOKEN_PRESET_NAME
)
400 snprintf(buf
, buf_size
, "%s", radio_get_preset(preset
)->name
);
404 int freq
= radio_get_preset(preset
)->frequency
/ 10000;
405 snprintf(buf
, buf_size
, "%d.%02d", freq
/100, freq
%100);
409 case WPS_TOKEN_PRESET_COUNT
:
410 snprintf(buf
, buf_size
, "%d", radio_preset_count());
412 *intval
= radio_preset_count();
414 case WPS_TOKEN_HAVE_RDS
:
417 case WPS_TOKEN_RDS_NAME
:
418 return tuner_get_rds_info(RADIO_RDS_NAME
);
419 case WPS_TOKEN_RDS_TEXT
:
420 return tuner_get_rds_info(RADIO_RDS_TEXT
);
422 return NULL
; /* end of the WPS_TOKEN_HAVE_RDS case */
423 #endif /* HAVE_RDS_CAP */
429 /* Return the tags value as text. buf should be used as temp storage if needed.
431 intval is used with conditionals/enums: when this function is called,
432 intval should contain the number of options in the conditional/enum.
433 When this function returns, intval is -1 if the tag is non numeric or,
434 if the tag is numeric, *intval is the enum case we want to go to (between 1
435 and the original value of *intval, inclusive).
436 When not treating a conditional/enum, intval should be NULL.
438 const char *get_token_value(struct gui_wps
*gwps
,
439 struct wps_token
*token
,
440 char *buf
, int buf_size
,
446 struct wps_data
*data
= gwps
->data
;
447 struct wps_state
*state
= gwps
->state
;
448 struct mp3entry
*id3
; /* Think very carefully about using this.
449 maybe get_id3_token() is the better place? */
450 const char *out_text
= NULL
;
462 struct tm
* tm
= NULL
;
464 /* if the token is an RTC one, update the time
465 and do the necessary checks */
466 if (token
->type
>= WPS_TOKENS_RTC_BEGIN
467 && token
->type
<= WPS_TOKENS_RTC_END
)
483 out_text
= get_id3_token(token
, id3
, buf
, buf_size
, limit
, intval
);
487 out_text
= get_radio_token(token
, 0, buf
, buf_size
, limit
, intval
);
494 case WPS_TOKEN_CHARACTER
:
495 if (token
->value
.c
== '\n')
497 return &(token
->value
.c
);
499 case WPS_TOKEN_STRING
:
500 return (char*)token
->value
.data
;
502 case WPS_TOKEN_TRANSLATEDSTRING
:
503 return (char*)P2STR(ID2P(token
->value
.i
));
505 case WPS_TOKEN_PLAYLIST_ENTRIES
:
506 snprintf(buf
, buf_size
, "%d", playlist_amount());
509 case WPS_TOKEN_LIST_TITLE_TEXT
:
510 return (char*)token
->value
.data
;
511 case WPS_TOKEN_LIST_TITLE_ICON
:
513 *intval
= token
->value
.i
;
514 snprintf(buf
, buf_size
, "%d", token
->value
.i
);
517 case WPS_TOKEN_PLAYLIST_NAME
:
518 return playlist_name(NULL
, buf
, buf_size
);
520 case WPS_TOKEN_PLAYLIST_POSITION
:
521 snprintf(buf
, buf_size
, "%d", playlist_get_display_index());
524 case WPS_TOKEN_PLAYLIST_SHUFFLE
:
525 if ( global_settings
.playlist_shuffle
)
531 case WPS_TOKEN_VOLUME
:
532 snprintf(buf
, buf_size
, "%d", global_settings
.volume
);
535 int minvol
= sound_min(SOUND_VOLUME
);
536 if (global_settings
.volume
== minvol
)
540 else if (global_settings
.volume
== 0)
544 else if (global_settings
.volume
> 0)
550 *intval
= (limit
-3) * (global_settings
.volume
- minvol
- 1)
556 case WPS_TOKEN_ALBUMART_FOUND
:
557 if (data
->albumart
) {
558 if (playback_current_aa_hid(data
->playback_aa_slot
) >= 0)
563 case WPS_TOKEN_ALBUMART_DISPLAY
:
566 if (!data
->albumart
->draw
)
567 data
->albumart
->draw
= true;
571 case WPS_TOKEN_BATTERY_PERCENT
:
573 int l
= battery_level();
577 limit
= MAX(limit
, 2);
579 /* First enum is used for "unknown level". */
580 *intval
= (limit
- 1) * l
/ 100 + 2;
587 snprintf(buf
, buf_size
, "%d", l
);
594 case WPS_TOKEN_BATTERY_VOLTS
:
596 unsigned int v
= battery_voltage();
597 snprintf(buf
, buf_size
, "%d.%02d", v
/ 1000, (v
% 1000) / 10);
601 case WPS_TOKEN_BATTERY_TIME
:
603 int t
= battery_time();
605 snprintf(buf
, buf_size
, "%dh %dm", t
/ 60, t
% 60);
612 case WPS_TOKEN_BATTERY_CHARGER_CONNECTED
:
614 if(charger_input_state
==CHARGER
)
620 #if CONFIG_CHARGING >= CHARGING_MONITOR
621 case WPS_TOKEN_BATTERY_CHARGING
:
623 if (charge_state
== CHARGING
|| charge_state
== TOPOFF
) {
630 #ifdef HAVE_USB_POWER
631 case WPS_TOKEN_USB_POWERED
:
636 case WPS_TOKEN_BATTERY_SLEEPTIME
:
638 if (get_sleep_timer() == 0)
642 format_time(buf
, buf_size
, get_sleep_timer() * 1000);
647 case WPS_TOKEN_PLAYBACK_STATUS
:
649 int status
= current_playmode();
651 int mode
= 1; /* stop */
652 if (status
== STATUS_PLAY
)
654 if (state
->is_fading
||
655 (status
== STATUS_PAUSE
&& !status_get_ffmode()))
656 mode
= 3; /* pause */
659 if (status_get_ffmode() == STATUS_FASTFORWARD
)
661 if (status_get_ffmode() == STATUS_FASTBACKWARD
)
664 #ifdef HAVE_RECORDING
666 if (status
== STATUS_RECORD
)
668 else if (status
== STATUS_RECORD_PAUSE
)
673 if (status
== STATUS_RADIO
)
675 else if (status
== STATUS_RADIO_PAUSE
)
683 snprintf(buf
, buf_size
, "%d", mode
-1);
687 case WPS_TOKEN_REPEAT_MODE
:
689 *intval
= global_settings
.repeat_mode
+ 1;
690 snprintf(buf
, buf_size
, "%d", global_settings
.repeat_mode
);
693 case WPS_TOKEN_RTC_PRESENT
:
701 case WPS_TOKEN_RTC_12HOUR_CFG
:
703 *intval
= global_settings
.timeformat
+ 1;
704 snprintf(buf
, buf_size
, "%d", global_settings
.timeformat
);
707 case WPS_TOKEN_RTC_DAY_OF_MONTH
:
708 /* d: day of month (01..31) */
709 snprintf(buf
, buf_size
, "%02d", tm
->tm_mday
);
711 *intval
= tm
->tm_mday
- 1;
714 case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED
:
715 /* e: day of month, blank padded ( 1..31) */
716 snprintf(buf
, buf_size
, "%2d", tm
->tm_mday
);
718 *intval
= tm
->tm_mday
- 1;
721 case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED
:
722 /* H: hour (00..23) */
723 snprintf(buf
, buf_size
, "%02d", tm
->tm_hour
);
725 *intval
= tm
->tm_hour
;
728 case WPS_TOKEN_RTC_HOUR_24
:
729 /* k: hour ( 0..23) */
730 snprintf(buf
, buf_size
, "%2d", tm
->tm_hour
);
732 *intval
= tm
->tm_hour
;
735 case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED
:
736 /* I: hour (01..12) */
737 snprintf(buf
, buf_size
, "%02d",
738 (tm
->tm_hour
% 12 == 0) ? 12 : tm
->tm_hour
% 12);
740 *intval
= (tm
->tm_hour
% 12 == 0) ? 12 : tm
->tm_hour
% 12;
743 case WPS_TOKEN_RTC_HOUR_12
:
744 /* l: hour ( 1..12) */
745 snprintf(buf
, buf_size
, "%2d",
746 (tm
->tm_hour
% 12 == 0) ? 12 : tm
->tm_hour
% 12);
748 *intval
= (tm
->tm_hour
% 12 == 0) ? 12 : tm
->tm_hour
% 12;
751 case WPS_TOKEN_RTC_MONTH
:
752 /* m: month (01..12) */
754 *intval
= tm
->tm_mon
+ 1;
755 snprintf(buf
, buf_size
, "%02d", tm
->tm_mon
+ 1);
758 case WPS_TOKEN_RTC_MINUTE
:
759 /* M: minute (00..59) */
760 snprintf(buf
, buf_size
, "%02d", tm
->tm_min
);
762 *intval
= tm
->tm_min
;
765 case WPS_TOKEN_RTC_SECOND
:
766 /* S: second (00..59) */
767 snprintf(buf
, buf_size
, "%02d", tm
->tm_sec
);
769 *intval
= tm
->tm_sec
;
772 case WPS_TOKEN_RTC_YEAR_2_DIGITS
:
773 /* y: last two digits of year (00..99) */
774 snprintf(buf
, buf_size
, "%02d", tm
->tm_year
% 100);
776 *intval
= tm
->tm_year
% 100;
779 case WPS_TOKEN_RTC_YEAR_4_DIGITS
:
780 /* Y: year (1970...) */
781 snprintf(buf
, buf_size
, "%04d", tm
->tm_year
+ 1900);
783 *intval
= tm
->tm_year
+ 1900;
786 case WPS_TOKEN_RTC_AM_PM_UPPER
:
787 /* p: upper case AM or PM indicator */
789 *intval
= tm
->tm_hour
/12 == 0 ? 0 : 1;
790 return tm
->tm_hour
/12 == 0 ? "AM" : "PM";
792 case WPS_TOKEN_RTC_AM_PM_LOWER
:
793 /* P: lower case am or pm indicator */
795 *intval
= tm
->tm_hour
/12 == 0 ? 0 : 1;
796 return tm
->tm_hour
/12 == 0 ? "am" : "pm";
798 case WPS_TOKEN_RTC_WEEKDAY_NAME
:
799 /* a: abbreviated weekday name (Sun..Sat) */
800 return str(LANG_WEEKDAY_SUNDAY
+ tm
->tm_wday
);
802 case WPS_TOKEN_RTC_MONTH_NAME
:
803 /* b: abbreviated month name (Jan..Dec) */
804 return str(LANG_MONTH_JANUARY
+ tm
->tm_mon
);
806 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON
:
807 /* u: day of week (1..7); 1 is Monday */
809 *intval
= (tm
->tm_wday
== 0) ? 7 : tm
->tm_wday
;
810 snprintf(buf
, buf_size
, "%1d", tm
->tm_wday
+ 1);
813 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN
:
814 /* w: day of week (0..6); 0 is Sunday */
816 *intval
= tm
->tm_wday
+ 1;
817 snprintf(buf
, buf_size
, "%1d", tm
->tm_wday
);
820 case WPS_TOKEN_RTC_DAY_OF_MONTH
:
821 case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED
:
822 case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED
:
823 case WPS_TOKEN_RTC_HOUR_24
:
824 case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED
:
825 case WPS_TOKEN_RTC_HOUR_12
:
826 case WPS_TOKEN_RTC_MONTH
:
827 case WPS_TOKEN_RTC_MINUTE
:
828 case WPS_TOKEN_RTC_SECOND
:
829 case WPS_TOKEN_RTC_AM_PM_UPPER
:
830 case WPS_TOKEN_RTC_AM_PM_LOWER
:
831 case WPS_TOKEN_RTC_YEAR_2_DIGITS
:
833 case WPS_TOKEN_RTC_YEAR_4_DIGITS
:
835 case WPS_TOKEN_RTC_WEEKDAY_NAME
:
836 case WPS_TOKEN_RTC_MONTH_NAME
:
838 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON
:
839 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN
:
843 #ifdef HAVE_LCD_CHARCELLS
844 case WPS_TOKEN_PROGRESSBAR
:
846 char *end
= utf8encode(data
->wps_progress_pat
[0], buf
);
851 case WPS_TOKEN_PLAYER_PROGRESSBAR
:
854 /* we need 11 characters (full line) for
856 strlcpy(buf
, " ", buf_size
);
860 /* Tell the user if we have an OldPlayer */
861 strlcpy(buf
, " <Old LCD> ", buf_size
);
868 #if (CONFIG_CODEC == SWCODEC)
869 case WPS_TOKEN_CROSSFADE
:
870 #ifdef HAVE_CROSSFADE
872 *intval
= global_settings
.crossfade
+ 1;
873 snprintf(buf
, buf_size
, "%d", global_settings
.crossfade
);
875 snprintf(buf
, buf_size
, "%d", 0);
879 case WPS_TOKEN_REPLAYGAIN
:
883 if (global_settings
.replaygain_type
== REPLAYGAIN_OFF
)
889 type
= get_replaygain_mode(id3
->track_gain_string
!= NULL
,
890 id3
->album_gain_string
!= NULL
);
895 val
= 6; /* no tag */
899 if (global_settings
.replaygain_type
== REPLAYGAIN_SHUFFLE
)
912 /* due to above, coming here with !id3 shouldn't be possible */
915 strlcpy(buf
, id3
->track_gain_string
, buf_size
);
919 strlcpy(buf
, id3
->album_gain_string
, buf_size
);
924 #endif /* (CONFIG_CODEC == SWCODEC) */
926 #if (CONFIG_CODEC != MAS3507D)
927 case WPS_TOKEN_SOUND_PITCH
:
929 int32_t pitch
= sound_get_pitch();
930 snprintf(buf
, buf_size
, "%ld.%ld",
931 pitch
/ PITCH_SPEED_PRECISION
,
932 (pitch
% PITCH_SPEED_PRECISION
) / (PITCH_SPEED_PRECISION
/ 10));
935 *intval
= pitch_speed_enum(limit
, pitch
,
936 PITCH_SPEED_PRECISION
* 100);
941 #if CONFIG_CODEC == SWCODEC
942 case WPS_TOKEN_SOUND_SPEED
:
944 int32_t pitch
= sound_get_pitch();
946 if (dsp_timestretch_available())
947 speed
= GET_SPEED(pitch
, dsp_get_timestretch());
950 snprintf(buf
, buf_size
, "%ld.%ld",
951 speed
/ PITCH_SPEED_PRECISION
,
952 (speed
% PITCH_SPEED_PRECISION
) / (PITCH_SPEED_PRECISION
/ 10));
954 *intval
= pitch_speed_enum(limit
, speed
,
955 PITCH_SPEED_PRECISION
* 100);
960 case WPS_TOKEN_MAIN_HOLD
:
961 #ifdef HAS_BUTTON_HOLD
964 if (is_keys_locked())
965 #endif /*hold switch or softlock*/
970 #ifdef HAS_REMOTE_BUTTON_HOLD
971 case WPS_TOKEN_REMOTE_HOLD
:
972 if (remote_button_hold())
978 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
979 case WPS_TOKEN_VLED_HDD
:
985 case WPS_TOKEN_BUTTON_VOLUME
:
986 if (global_status
.last_volume_change
&&
987 TIME_BEFORE(current_tick
, global_status
.last_volume_change
+
988 token
->value
.i
* TIMEOUT_UNIT
))
992 case WPS_TOKEN_TRACK_STARTING
:
995 int elapsed
= id3
->elapsed
+ state
->ff_rewind_count
;
996 if (elapsed
< token
->value
.i
* 1000)
1000 case WPS_TOKEN_TRACK_ENDING
:
1003 unsigned long elapsed
= id3
->elapsed
+ state
->ff_rewind_count
;
1004 unsigned time
= token
->value
.i
* 1000;
1005 if (id3
->length
- elapsed
< time
)
1009 case WPS_TOKEN_LASTTOUCH
:
1010 #ifdef HAVE_TOUCHSCREEN
1011 if (TIME_BEFORE(current_tick
, token
->value
.i
* TIMEOUT_UNIT
+
1012 touchscreen_last_touch()))
1017 case WPS_TOKEN_SETTING
:
1019 const struct settings_list
*s
= settings
+token
->value
.i
;
1022 /* Handle contionals */
1023 switch (s
->flags
&F_T_MASK
)
1027 if (s
->flags
&F_T_SOUND
)
1029 /* %?St|name|<min|min+1|...|max-1|max> */
1030 int sound_setting
= s
->sound_setting
->setting
;
1031 /* settings with decimals can't be used in conditionals */
1032 if (sound_numdecimals(sound_setting
) == 0)
1034 *intval
= (*(int*)s
->setting
-sound_min(sound_setting
))
1035 /sound_steps(sound_setting
) + 1;
1040 else if (s
->flags
&F_RGB
)
1041 /* %?St|name|<#000000|#000001|...|#FFFFFF> */
1042 /* shouldn't overflow since colors are stored
1044 * but this is pretty useless anyway */
1045 *intval
= *(int*)s
->setting
+ 1;
1046 else if (s
->cfg_vals
== NULL
)
1047 /* %?St|name|<1st choice|2nd choice|...> */
1048 *intval
= (*(int*)s
->setting
-s
->int_setting
->min
)
1049 /s
->int_setting
->step
+ 1;
1051 /* %?St|name|<1st choice|2nd choice|...> */
1052 /* Not sure about this one. cfg_name/vals are
1053 * indexed from 0 right? */
1054 *intval
= *(int*)s
->setting
+ 1;
1057 /* %?St|name|<if true|if false> */
1058 *intval
= *(bool*)s
->setting
?1:2;
1062 /* %?St|name|<if non empty string|if empty>
1063 * The string's emptyness discards the setting's
1064 * prefix and suffix */
1065 *intval
= ((char*)s
->setting
)[0]?1:2;
1066 /* if there is a prefix we should ignore it here */
1067 if (s
->filename_setting
->prefix
)
1068 return (char*)s
->setting
;
1071 /* This shouldn't happen ... but you never know */
1076 /* Special handlng for filenames because we dont want to show the prefix */
1077 if ((s
->flags
&F_T_MASK
) == F_T_UCHARPTR
||
1078 (s
->flags
&F_T_MASK
) == F_T_UCHARPTR
)
1080 if (s
->filename_setting
->prefix
)
1081 return (char*)s
->setting
;
1083 cfg_to_string(token
->value
.i
,buf
,buf_size
);
1086 case WPS_TOKEN_HAVE_TUNER
:
1088 if (radio_hardware_present())
1092 /* Recording tokens */
1093 case WPS_TOKEN_HAVE_RECORDING
:
1094 #ifdef HAVE_RECORDING
1100 #ifdef HAVE_RECORDING
1101 case WPS_TOKEN_IS_RECORDING
:
1102 if (audio_status() == AUDIO_STATUS_RECORD
)
1105 case WPS_TOKEN_REC_FREQ
: /* order from REC_FREQ_CFG_VAL_LIST */
1107 #if CONFIG_CODEC == SWCODEC
1108 unsigned long samprk
;
1109 int rec_freq
= global_settings
.rec_frequency
;
1114 #if defined(HAVE_SPDIF_REC)
1115 if (global_settings
.rec_source
== AUDIO_SRC_SPDIF
)
1117 /* Use rate in use, not current measured rate if it changed */
1118 samprk
= pcm_rec_sample_rate();
1120 while (rec_freq
< SAMPR_NUM_FREQ
&&
1121 audio_master_sampr_list
[rec_freq
] != samprk
)
1128 samprk
= rec_freq_sampr
[rec_freq
];
1129 #endif /* SIMULATOR */
1134 REC_HAVE_96_(case REC_FREQ_96
:
1137 REC_HAVE_88_(case REC_FREQ_88
:
1140 REC_HAVE_64_(case REC_FREQ_64
:
1143 REC_HAVE_48_(case REC_FREQ_48
:
1146 REC_HAVE_44_(case REC_FREQ_44
:
1149 REC_HAVE_32_(case REC_FREQ_32
:
1152 REC_HAVE_24_(case REC_FREQ_24
:
1155 REC_HAVE_22_(case REC_FREQ_22
:
1158 REC_HAVE_16_(case REC_FREQ_16
:
1161 REC_HAVE_12_(case REC_FREQ_12
:
1164 REC_HAVE_11_(case REC_FREQ_11
:
1167 REC_HAVE_8_(case REC_FREQ_8
:
1172 snprintf(buf
, buf_size
, "%lu.%1lu", samprk
/1000,samprk
%1000);
1175 static const char * const freq_strings
[] =
1176 {"--", "44", "48", "32", "22", "24", "16"};
1177 int freq
= 1 + global_settings
.rec_frequency
;
1178 #ifdef HAVE_SPDIF_REC
1179 if (global_settings
.rec_source
== AUDIO_SRC_SPDIF
)
1181 /* Can't measure S/PDIF sample rate on Archos/Sim yet */
1184 #endif /* HAVE_SPDIF_IN */
1186 *intval
= freq
+1; /* so the token gets a value 1<=x<=7 */
1187 snprintf(buf
, buf_size
, "%s\n",
1188 freq_strings
[global_settings
.rec_frequency
]);
1192 #if CONFIG_CODEC == SWCODEC
1193 case WPS_TOKEN_REC_ENCODER
:
1195 int rec_format
= global_settings
.rec_format
+1; /* WAV, AIFF, WV, MPEG */
1197 *intval
= rec_format
;
1200 case REC_FORMAT_PCM_WAV
:
1202 case REC_FORMAT_AIFF
:
1204 case REC_FORMAT_WAVPACK
:
1206 case REC_FORMAT_MPA_L3
:
1214 case WPS_TOKEN_REC_BITRATE
:
1215 #if CONFIG_CODEC == SWCODEC
1216 if (global_settings
.rec_format
== REC_FORMAT_MPA_L3
)
1220 #if 0 /* FIXME: I dont know if this is needed? */
1221 switch (1<<global_settings
.mp3_enc_config
.bitrate
)
1223 case MP3_BITR_CAP_8
:
1226 case MP3_BITR_CAP_16
:
1229 case MP3_BITR_CAP_24
:
1232 case MP3_BITR_CAP_32
:
1235 case MP3_BITR_CAP_40
:
1238 case MP3_BITR_CAP_48
:
1241 case MP3_BITR_CAP_56
:
1244 case MP3_BITR_CAP_64
:
1247 case MP3_BITR_CAP_80
:
1250 case MP3_BITR_CAP_96
:
1253 case MP3_BITR_CAP_112
:
1256 case MP3_BITR_CAP_128
:
1259 case MP3_BITR_CAP_144
:
1262 case MP3_BITR_CAP_160
:
1265 case MP3_BITR_CAP_192
:
1270 *intval
= global_settings
.mp3_enc_config
.bitrate
+1;
1272 snprintf(buf
, buf_size
, "%lu", global_settings
.mp3_enc_config
.bitrate
+1);
1276 return NULL
; /* Fixme later */
1277 #else /* CONFIG_CODEC == HWCODEC */
1279 *intval
= global_settings
.rec_quality
+1;
1280 snprintf(buf
, buf_size
, "%d", global_settings
.rec_quality
);
1283 case WPS_TOKEN_REC_MONO
:
1284 if (!global_settings
.rec_channels
)
1288 case WPS_TOKEN_REC_SECONDS
:
1290 int time
= (audio_recorded_time() / HZ
) % 60;
1293 snprintf(buf
, buf_size
, "%02d", time
);
1296 case WPS_TOKEN_REC_MINUTES
:
1298 int time
= (audio_recorded_time() / HZ
) / 60;
1301 snprintf(buf
, buf_size
, "%02d", time
);
1304 case WPS_TOKEN_REC_HOURS
:
1306 int time
= (audio_recorded_time() / HZ
) / 3600;
1309 snprintf(buf
, buf_size
, "%02d", time
);
1313 #endif /* HAVE_RECORDING */
1315 case WPS_TOKEN_CURRENT_SCREEN
:
1317 int curr_screen
= current_screen();
1319 #ifdef HAVE_RECORDING
1320 /* override current_screen() for recording screen since it may
1321 * be entered from the radio screen */
1322 if (in_recording_screen())
1323 curr_screen
= GO_TO_RECSCREEN
;
1326 switch (curr_screen
)
1331 #ifdef HAVE_RECORDING
1332 case GO_TO_RECSCREEN
:
1341 case GO_TO_PLAYLIST_VIEWER
:
1344 default: /* lists */
1350 *intval
= curr_screen
;
1352 snprintf(buf
, buf_size
, "%d", curr_screen
);
1356 case WPS_TOKEN_LANG_IS_RTL
:
1357 return lang_is_rtl() ? "r" : NULL
;