forked from len0rd/rockbox
First step of the voice-UI: the menus can talk. You need a "voicefont" file in .rockbox to use this.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4381 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
62b095d029
commit
4f36ea8fbf
18 changed files with 454 additions and 122 deletions
|
|
@ -93,9 +93,9 @@ bool bookmark_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_BOOKMARK_MENU_CREATE), bookmark_create_menu},
|
||||
{ str(LANG_BOOKMARK_MENU_LIST), bookmark_load_menu},
|
||||
{ str(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS), bookmark_mrb_load},
|
||||
{ STR(LANG_BOOKMARK_MENU_CREATE), bookmark_create_menu},
|
||||
{ STR(LANG_BOOKMARK_MENU_LIST), bookmark_load_menu},
|
||||
{ STR(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS), bookmark_mrb_load},
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof items / sizeof(struct menu_items), NULL );
|
||||
|
|
|
|||
|
|
@ -1476,36 +1476,36 @@ bool debug_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ "Dump ROM contents", dbg_save_roms },
|
||||
{ "View I/O ports", dbg_ports },
|
||||
{ "Dump ROM contents", -1, dbg_save_roms },
|
||||
{ "View I/O ports", -1, dbg_ports },
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
#ifdef HAVE_RTC
|
||||
{ "View/clr RTC RAM", dbg_rtc },
|
||||
{ "View/clr RTC RAM", -1, dbg_rtc },
|
||||
#endif /* HAVE_RTC */
|
||||
#endif /* HAVE_LCD_BITMAP */
|
||||
{ "View OS stacks", dbg_os },
|
||||
{ "View OS stacks", -1, dbg_os },
|
||||
#ifdef HAVE_MAS3507D
|
||||
{ "View MAS info", dbg_mas_info },
|
||||
{ "View MAS info", -1, dbg_mas_info },
|
||||
#endif
|
||||
{ "View MAS regs", dbg_mas },
|
||||
{ "View MAS regs", -1, dbg_mas },
|
||||
#ifdef HAVE_MAS3587F
|
||||
{ "View MAS codec", dbg_mas_codec },
|
||||
{ "View MAS codec", -1, dbg_mas_codec },
|
||||
#endif
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
{ "View battery", view_battery },
|
||||
{ "View battery", -1, view_battery },
|
||||
#endif
|
||||
{ "View HW info", dbg_hw_info },
|
||||
{ "View partitions", dbg_partitions },
|
||||
{ "View disk info", dbg_disk_info },
|
||||
{ "View HW info", -1, dbg_hw_info },
|
||||
{ "View partitions", -1, dbg_partitions },
|
||||
{ "View disk info", -1, dbg_disk_info },
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
{ "View mpeg thread", dbg_mpeg_thread },
|
||||
{ "View mpeg thread", -1, dbg_mpeg_thread },
|
||||
#ifdef PM_DEBUG
|
||||
{ "pm histogram", peak_meter_histogram},
|
||||
{ "pm histogram", -1, peak_meter_histogram},
|
||||
#endif /* PM_DEBUG */
|
||||
#endif /* HAVE_LCD_BITMAP */
|
||||
{ "View runtime", view_runtime },
|
||||
{ "View runtime", -1, view_runtime },
|
||||
#ifdef HAVE_FMRADIO
|
||||
{ "FM Radio", dbg_fm_radio },
|
||||
{ "FM Radio", -1, dbg_fm_radio },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include "rolo.h"
|
||||
#include "screens.h"
|
||||
#include "power.h"
|
||||
#include "talk.h"
|
||||
|
||||
char appsversion[]=APPSVERSION;
|
||||
|
||||
|
|
@ -208,6 +209,7 @@ void init(void)
|
|||
global_settings.avc,
|
||||
global_settings.channel_config );
|
||||
mpeg_init();
|
||||
talk_init();
|
||||
|
||||
/* no auto-rolo on startup any more, but I leave it here for reference */
|
||||
#if 0
|
||||
|
|
|
|||
|
|
@ -262,8 +262,8 @@ bool rec_menu(void)
|
|||
|
||||
/* recording menu */
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_RECORDING_MENU), recording_screen },
|
||||
{ str(LANG_RECORDING_SETTINGS), recording_settings},
|
||||
{ STR(LANG_RECORDING_MENU), recording_screen },
|
||||
{ STR(LANG_RECORDING_SETTINGS), recording_settings},
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof items / sizeof(struct menu_items), NULL );
|
||||
|
|
@ -281,13 +281,13 @@ bool info_menu(void)
|
|||
|
||||
/* info menu */
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_MENU_SHOW_ID3_INFO), browse_id3 },
|
||||
{ str(LANG_INFO_MENU), show_info },
|
||||
{ str(LANG_VERSION), show_credits },
|
||||
{ STR(LANG_MENU_SHOW_ID3_INFO), browse_id3 },
|
||||
{ STR(LANG_INFO_MENU), show_info },
|
||||
{ STR(LANG_VERSION), show_credits },
|
||||
#ifndef SIMULATOR
|
||||
{ str(LANG_DEBUG), debug_menu },
|
||||
{ STR(LANG_DEBUG), debug_menu },
|
||||
#else
|
||||
{ str(LANG_USB), simulate_usb },
|
||||
{ STR(LANG_USB), simulate_usb },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -308,33 +308,41 @@ bool main_menu(void)
|
|||
struct menu_items items[8];
|
||||
|
||||
items[i].desc = str(LANG_BOOKMARK_MENU);
|
||||
items[i].voice_id = LANG_BOOKMARK_MENU;
|
||||
items[i++].function = bookmark_menu;
|
||||
|
||||
items[i].desc = str(LANG_SOUND_SETTINGS);
|
||||
items[i].voice_id = LANG_SOUND_SETTINGS;
|
||||
items[i++].function = sound_menu;
|
||||
|
||||
items[i].desc = str(LANG_GENERAL_SETTINGS);
|
||||
items[i].voice_id = LANG_GENERAL_SETTINGS;
|
||||
items[i++].function = settings_menu;
|
||||
|
||||
#ifdef HAVE_FMRADIO
|
||||
if(radio_hardware_present()) {
|
||||
items[i].desc = str(LANG_FM_RADIO);
|
||||
items[i].voice_id = LANG_FM_RADIO;
|
||||
items[i++].function = radio_screen;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MAS3587F
|
||||
items[i].desc = str(LANG_RECORDING);
|
||||
items[i].voice_id = LANG_RECORDING;
|
||||
items[i++].function = rec_menu;
|
||||
#endif
|
||||
|
||||
items[i].desc = str(LANG_PLAYLIST_MENU);
|
||||
items[i].voice_id = LANG_PLAYLIST_MENU;
|
||||
items[i++].function = playlist_menu;
|
||||
|
||||
items[i].desc = str(LANG_PLUGINS);
|
||||
items[i].voice_id = LANG_PLUGINS;
|
||||
items[i++].function = plugin_browse;
|
||||
|
||||
items[i].desc = str(LANG_INFO);
|
||||
items[i].voice_id = LANG_INFO;
|
||||
items[i++].function = info_menu;
|
||||
|
||||
m=menu_init( items, i, NULL );
|
||||
|
|
|
|||
17
apps/menu.c
17
apps/menu.c
|
|
@ -32,6 +32,7 @@
|
|||
#include "settings.h"
|
||||
#include "status.h"
|
||||
#include "screens.h"
|
||||
#include "talk.h"
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
#include "icons.h"
|
||||
|
|
@ -216,6 +217,13 @@ static void put_cursor(int m, int target)
|
|||
lcd_update();
|
||||
}
|
||||
|
||||
if (do_update)
|
||||
{ /* "say" the entry under the cursor */
|
||||
int voice_id = menus[m].items[menus[m].cursor].voice_id;
|
||||
if (voice_id >= 0) /* valid ID given? */
|
||||
talk_id(voice_id, false); /* say it */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int menu_init(struct menu_items* mitems, int count, int (*callback)(int, int))
|
||||
|
|
@ -250,6 +258,7 @@ int menu_show(int m)
|
|||
{
|
||||
bool exit = false;
|
||||
int key;
|
||||
int voice_id;
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
int fw, fh;
|
||||
int menu_lines;
|
||||
|
|
@ -263,9 +272,16 @@ int menu_show(int m)
|
|||
|
||||
menu_draw(m);
|
||||
|
||||
/* say current entry */
|
||||
voice_id = menus[m].items[menus[m].cursor].voice_id;
|
||||
if (voice_id >= 0) /* valid ID given? */
|
||||
talk_id(voice_id, false); /* say it */
|
||||
|
||||
while (!exit) {
|
||||
key = button_get_w_tmo(HZ/2);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* "short-circuit" the default keypresses by running the callback function
|
||||
*/
|
||||
|
|
@ -274,6 +290,7 @@ int menu_show(int m)
|
|||
key = menus[m].callback(key, m); /* make sure there's no match in the switch */
|
||||
|
||||
switch( key ) {
|
||||
|
||||
#ifdef HAVE_RECORDER_KEYPAD
|
||||
case BUTTON_UP:
|
||||
case BUTTON_UP | BUTTON_REPEAT:
|
||||
|
|
|
|||
|
|
@ -23,10 +23,14 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
struct menu_items {
|
||||
unsigned char *desc;
|
||||
unsigned char *desc; /* string */
|
||||
int voice_id; /* the associated voice clip, -1 if none */
|
||||
bool (*function) (void); /* return true if USB was connected */
|
||||
};
|
||||
|
||||
/* convenience macro to have both string and ID as arguments */
|
||||
#define STR(id) str(id), id
|
||||
|
||||
int menu_init(struct menu_items* items, int count, int (*callback) (int keycode, int menu));
|
||||
void menu_exit(int menu);
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include "settings.h"
|
||||
#include "status.h"
|
||||
#include "playlist_viewer.h"
|
||||
#include "talk.h"
|
||||
#include "onplay.h"
|
||||
|
||||
static char* selected_file = NULL;
|
||||
|
|
@ -147,6 +148,7 @@ static bool playlist_options(void)
|
|||
if ((selected_file_attr & TREE_ATTR_MASK) == TREE_ATTR_M3U)
|
||||
{
|
||||
menu[i].desc = str(LANG_VIEW);
|
||||
menu[i].voice_id = LANG_VIEW;
|
||||
menu[i].function = view_playlist;
|
||||
i++;
|
||||
pstart++;
|
||||
|
|
@ -155,31 +157,37 @@ static bool playlist_options(void)
|
|||
if (mpeg_status() & MPEG_STATUS_PLAY)
|
||||
{
|
||||
menu[i].desc = str(LANG_INSERT);
|
||||
menu[i].voice_id = LANG_INSERT;
|
||||
args[i].position = PLAYLIST_INSERT;
|
||||
args[i].queue = false;
|
||||
i++;
|
||||
|
||||
menu[i].desc = str(LANG_INSERT_FIRST);
|
||||
menu[i].voice_id = LANG_INSERT_FIRST;
|
||||
args[i].position = PLAYLIST_INSERT_FIRST;
|
||||
args[i].queue = false;
|
||||
i++;
|
||||
|
||||
menu[i].desc = str(LANG_INSERT_LAST);
|
||||
menu[i].voice_id = LANG_INSERT_LAST;
|
||||
args[i].position = PLAYLIST_INSERT_LAST;
|
||||
args[i].queue = false;
|
||||
i++;
|
||||
|
||||
menu[i].desc = str(LANG_QUEUE);
|
||||
menu[i].voice_id = LANG_QUEUE;
|
||||
args[i].position = PLAYLIST_INSERT;
|
||||
args[i].queue = true;
|
||||
i++;
|
||||
|
||||
menu[i].desc = str(LANG_QUEUE_FIRST);
|
||||
menu[i].voice_id = LANG_QUEUE_FIRST;
|
||||
args[i].position = PLAYLIST_INSERT_FIRST;
|
||||
args[i].queue = true;
|
||||
i++;
|
||||
|
||||
menu[i].desc = str(LANG_QUEUE_LAST);
|
||||
menu[i].voice_id = LANG_QUEUE_LAST;
|
||||
args[i].position = PLAYLIST_INSERT_LAST;
|
||||
args[i].queue = true;
|
||||
i++;
|
||||
|
|
@ -188,6 +196,7 @@ static bool playlist_options(void)
|
|||
(selected_file_attr & ATTR_DIRECTORY))
|
||||
{
|
||||
menu[i].desc = str(LANG_INSERT);
|
||||
menu[i].voice_id = LANG_INSERT;
|
||||
args[i].position = PLAYLIST_INSERT;
|
||||
args[i].queue = false;
|
||||
i++;
|
||||
|
|
@ -283,6 +292,8 @@ static int insert_data_in_file(char *fname, int fpos, char *buf, int num_bytes)
|
|||
int orig_fd, fd;
|
||||
char tmpname[MAX_PATH];
|
||||
|
||||
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
|
||||
|
||||
snprintf(tmpname, MAX_PATH, "%s.tmp", fname);
|
||||
|
||||
orig_fd = open(fname, O_RDONLY);
|
||||
|
|
@ -384,6 +395,8 @@ static bool vbr_fix(void)
|
|||
return onplay_result;
|
||||
}
|
||||
|
||||
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
|
||||
|
||||
lcd_clear_display();
|
||||
lcd_puts_scroll(0, 0, selected_file);
|
||||
lcd_update();
|
||||
|
|
@ -552,17 +565,20 @@ int onplay(char* file, int attr)
|
|||
((attr & TREE_ATTR_MASK) == TREE_ATTR_M3U))
|
||||
{
|
||||
menu[i].desc = str(LANG_PLAYINDICES_PLAYLIST);
|
||||
menu[i].voice_id = LANG_PLAYINDICES_PLAYLIST;
|
||||
menu[i].function = playlist_options;
|
||||
i++;
|
||||
}
|
||||
|
||||
menu[i].desc = str(LANG_RENAME);
|
||||
menu[i].voice_id = LANG_RENAME;
|
||||
menu[i].function = rename_file;
|
||||
i++;
|
||||
|
||||
if (!(attr & ATTR_DIRECTORY))
|
||||
{
|
||||
menu[i].desc = str(LANG_DELETE);
|
||||
menu[i].voice_id = LANG_DELETE;
|
||||
menu[i].function = delete_file;
|
||||
i++;
|
||||
}
|
||||
|
|
@ -570,12 +586,14 @@ int onplay(char* file, int attr)
|
|||
if ((attr & TREE_ATTR_MASK) == TREE_ATTR_MPA)
|
||||
{
|
||||
menu[i].desc = str(LANG_VBRFIX);
|
||||
menu[i].voice_id = LANG_VBRFIX;
|
||||
menu[i].function = vbr_fix;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
menu[i].desc = str(LANG_CREATE_DIR);
|
||||
menu[i].voice_id = LANG_CREATE_DIR;
|
||||
menu[i].function = create_dir;
|
||||
i++;
|
||||
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@
|
|||
#endif
|
||||
|
||||
#include "lang.h"
|
||||
#include "talk.h"
|
||||
|
||||
#define PLAYLIST_CONTROL_FILE ROCKBOX_DIR "/.playlist_control"
|
||||
#define PLAYLIST_CONTROL_FILE_VERSION 2
|
||||
|
|
@ -337,6 +338,7 @@ static int add_indices_to_playlist(struct playlist_info* playlist,
|
|||
{
|
||||
/* use mp3 buffer for maximum load speed */
|
||||
mpeg_stop();
|
||||
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
|
||||
|
||||
buffer = mp3buf;
|
||||
buflen = (mp3end - mp3buf);
|
||||
|
|
@ -1192,6 +1194,7 @@ int playlist_resume(void)
|
|||
};
|
||||
|
||||
/* use mp3 buffer for maximum load speed */
|
||||
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
|
||||
buflen = (mp3end - mp3buf);
|
||||
buffer = mp3buf;
|
||||
|
||||
|
|
|
|||
|
|
@ -65,10 +65,10 @@ bool playlist_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_CREATE_PLAYLIST), create_playlist },
|
||||
{ str(LANG_VIEW_DYNAMIC_PLAYLIST), playlist_viewer },
|
||||
{ str(LANG_SAVE_DYNAMIC_PLAYLIST), save_playlist },
|
||||
{ str(LANG_RECURSE_DIRECTORY), recurse_directory },
|
||||
{ STR(LANG_CREATE_PLAYLIST), create_playlist },
|
||||
{ STR(LANG_VIEW_DYNAMIC_PLAYLIST), playlist_viewer },
|
||||
{ STR(LANG_SAVE_DYNAMIC_PLAYLIST), save_playlist },
|
||||
{ STR(LANG_RECURSE_DIRECTORY), recurse_directory },
|
||||
};
|
||||
|
||||
m = menu_init( items, sizeof items / sizeof(struct menu_items), NULL );
|
||||
|
|
|
|||
|
|
@ -685,12 +685,15 @@ static int onplay_menu(int index)
|
|||
bool current = (tracks[index].index == viewer.current_playing_track);
|
||||
|
||||
menu[i].desc = str(LANG_REMOVE);
|
||||
menu[i].voice_id = LANG_REMOVE;
|
||||
i++;
|
||||
|
||||
menu[i].desc = str(LANG_MOVE);
|
||||
menu[i].voice_id = LANG_MOVE;
|
||||
i++;
|
||||
|
||||
menu[i].desc = str(LANG_FILE_OPTIONS);
|
||||
menu[i].voice_id = LANG_FILE_OPTIONS;
|
||||
i++;
|
||||
|
||||
m = menu_init(menu, i, NULL);
|
||||
|
|
@ -757,10 +760,10 @@ static bool viewer_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_SHOW_ICONS), show_icons },
|
||||
{ str(LANG_SHOW_INDICES), show_indices },
|
||||
{ str(LANG_TRACK_DISPLAY), track_display },
|
||||
{ str(LANG_SAVE_DYNAMIC_PLAYLIST), save_playlist },
|
||||
{ STR(LANG_SHOW_ICONS), show_icons },
|
||||
{ STR(LANG_SHOW_INDICES), show_indices },
|
||||
{ STR(LANG_TRACK_DISPLAY), track_display },
|
||||
{ STR(LANG_SAVE_DYNAMIC_PLAYLIST), save_playlist },
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "mp3_playback.h"
|
||||
#include "backlight.h"
|
||||
#include "ata.h"
|
||||
#include "talk.h"
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
#include "widgets.h"
|
||||
|
|
@ -325,6 +326,7 @@ void* plugin_get_mp3_buffer(int* buffer_size)
|
|||
return buf;
|
||||
#else
|
||||
mpeg_stop();
|
||||
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
|
||||
*buffer_size = mp3end - mp3buf;
|
||||
return mp3buf;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -595,6 +595,7 @@ bool radio_preset_select(void)
|
|||
if(presets[i].frequency)
|
||||
{
|
||||
menu[num_presets].desc = presets[i].name;
|
||||
menu[num_presets].voice_id = -1;
|
||||
/* We use the function pointer entry for the preset
|
||||
entry index */
|
||||
menu[num_presets++].function = (void *)i;
|
||||
|
|
@ -669,6 +670,7 @@ bool radio_delete_preset(void)
|
|||
if(presets[i].frequency)
|
||||
{
|
||||
menu[num_presets].desc = presets[i].name;
|
||||
menu[num_presets].voice_id = -1;
|
||||
/* We use the function pointer entry for the preset
|
||||
entry index */
|
||||
menu[num_presets++].function = (void *)i;
|
||||
|
|
@ -715,10 +717,10 @@ static bool fm_recording_settings(void)
|
|||
bool radio_menu(void)
|
||||
{
|
||||
struct menu_items radio_menu_items[] = {
|
||||
{ str(LANG_FM_SAVE_PRESET), radio_add_preset },
|
||||
{ str(LANG_FM_DELETE_PRESET), radio_delete_preset },
|
||||
{ str(LANG_SOUND_SETTINGS), sound_menu },
|
||||
{ str(LANG_RECORDING_SETTINGS), fm_recording_settings }
|
||||
{ STR(LANG_FM_SAVE_PRESET), radio_add_preset },
|
||||
{ STR(LANG_FM_DELETE_PRESET), radio_delete_preset },
|
||||
{ STR(LANG_SOUND_SETTINGS), sound_menu },
|
||||
{ STR(LANG_RECORDING_SETTINGS), fm_recording_settings }
|
||||
};
|
||||
int m;
|
||||
bool result;
|
||||
|
|
|
|||
|
|
@ -368,16 +368,16 @@ static bool peak_meter_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_PM_RELEASE) , peak_meter_release },
|
||||
{ str(LANG_PM_PEAK_HOLD), peak_meter_hold },
|
||||
{ str(LANG_PM_CLIP_HOLD), peak_meter_clip_hold },
|
||||
{ str(LANG_PM_PERFORMANCE), peak_meter_performance },
|
||||
{ STR(LANG_PM_RELEASE) , peak_meter_release },
|
||||
{ STR(LANG_PM_PEAK_HOLD), peak_meter_hold },
|
||||
{ STR(LANG_PM_CLIP_HOLD), peak_meter_clip_hold },
|
||||
{ STR(LANG_PM_PERFORMANCE), peak_meter_performance },
|
||||
#ifdef PM_DEBUG
|
||||
{ "Refresh rate" , peak_meter_fps_menu },
|
||||
{ "Refresh rate" , -1 , peak_meter_fps_menu },
|
||||
#endif
|
||||
{ str(LANG_PM_SCALE) , peak_meter_scale },
|
||||
{ str(LANG_PM_MIN) , peak_meter_min },
|
||||
{ str(LANG_PM_MAX) , peak_meter_max },
|
||||
{ STR(LANG_PM_SCALE) , peak_meter_scale },
|
||||
{ STR(LANG_PM_MIN) , peak_meter_min },
|
||||
{ STR(LANG_PM_MAX) , peak_meter_max },
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
|
||||
|
|
@ -791,8 +791,8 @@ static bool ff_rewind_settings_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_FFRW_STEP), ff_rewind_min_step },
|
||||
{ str(LANG_FFRW_ACCEL), ff_rewind_accel },
|
||||
{ STR(LANG_FFRW_STEP), ff_rewind_min_step },
|
||||
{ STR(LANG_FFRW_ACCEL), ff_rewind_accel },
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
|
||||
|
|
@ -808,13 +808,13 @@ static bool playback_settings_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_SHUFFLE), shuffle },
|
||||
{ str(LANG_REPEAT), repeat_mode },
|
||||
{ str(LANG_PLAY_SELECTED), play_selected },
|
||||
{ str(LANG_RESUME), resume },
|
||||
{ str(LANG_WIND_MENU), ff_rewind_settings_menu },
|
||||
{ str(LANG_MP3BUFFER_MARGIN), buffer_margin },
|
||||
{ str(LANG_FADE_ON_STOP), set_fade_on_stop },
|
||||
{ STR(LANG_SHUFFLE), shuffle },
|
||||
{ STR(LANG_REPEAT), repeat_mode },
|
||||
{ STR(LANG_PLAY_SELECTED), play_selected },
|
||||
{ STR(LANG_RESUME), resume },
|
||||
{ STR(LANG_WIND_MENU), ff_rewind_settings_menu },
|
||||
{ STR(LANG_MP3BUFFER_MARGIN), buffer_margin },
|
||||
{ STR(LANG_FADE_ON_STOP), set_fade_on_stop },
|
||||
};
|
||||
|
||||
bool old_shuffle = global_settings.playlist_shuffle;
|
||||
|
|
@ -843,9 +843,9 @@ static bool bookmark_settings_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_BOOKMARK_SETTINGS_AUTOCREATE), autocreatebookmark},
|
||||
{ str(LANG_BOOKMARK_SETTINGS_AUTOLOAD), autoloadbookmark},
|
||||
{ str(LANG_BOOKMARK_SETTINGS_MAINTAIN_RECENT_BOOKMARKS), useMRB},
|
||||
{ STR(LANG_BOOKMARK_SETTINGS_AUTOCREATE), autocreatebookmark},
|
||||
{ STR(LANG_BOOKMARK_SETTINGS_AUTOLOAD), autoloadbookmark},
|
||||
{ STR(LANG_BOOKMARK_SETTINGS_MAINTAIN_RECENT_BOOKMARKS), useMRB},
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof items / sizeof(struct menu_items), NULL );
|
||||
|
|
@ -910,10 +910,10 @@ static bool fileview_settings_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_CASE_MENU), sort_case },
|
||||
{ str(LANG_FILTER), dir_filter },
|
||||
{ str(LANG_FOLLOW), browse_current },
|
||||
{ str(LANG_SHOW_ICONS), show_icons },
|
||||
{ STR(LANG_CASE_MENU), sort_case },
|
||||
{ STR(LANG_FILTER), dir_filter },
|
||||
{ STR(LANG_FOLLOW), browse_current },
|
||||
{ STR(LANG_SHOW_ICONS), show_icons },
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
|
||||
|
|
@ -929,15 +929,15 @@ static bool scroll_settings_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_SCROLL_SPEED), scroll_speed },
|
||||
{ str(LANG_SCROLL_DELAY), scroll_delay },
|
||||
{ STR(LANG_SCROLL_SPEED), scroll_speed },
|
||||
{ STR(LANG_SCROLL_DELAY), scroll_delay },
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
{ str(LANG_SCROLL_STEP), scroll_step },
|
||||
{ STR(LANG_SCROLL_STEP), scroll_step },
|
||||
#endif
|
||||
{ str(LANG_BIDIR_SCROLL), bidir_limit },
|
||||
{ STR(LANG_BIDIR_SCROLL), bidir_limit },
|
||||
#ifdef HAVE_LCD_CHARCELLS
|
||||
{ str(LANG_JUMP_SCROLL), jump_scroll },
|
||||
{ str(LANG_JUMP_SCROLL_DELAY), jump_scroll_delay },
|
||||
{ STR(LANG_JUMP_SCROLL), jump_scroll },
|
||||
{ STR(LANG_JUMP_SCROLL_DELAY), jump_scroll_delay },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -953,14 +953,14 @@ static bool lcd_settings_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_BACKLIGHT), backlight_timer },
|
||||
{ str(LANG_BACKLIGHT_ON_WHEN_CHARGING), backlight_on_when_charging },
|
||||
{ str(LANG_CAPTION_BACKLIGHT), caption_backlight },
|
||||
{ str(LANG_CONTRAST), contrast },
|
||||
{ STR(LANG_BACKLIGHT), backlight_timer },
|
||||
{ STR(LANG_BACKLIGHT_ON_WHEN_CHARGING), backlight_on_when_charging },
|
||||
{ STR(LANG_CAPTION_BACKLIGHT), caption_backlight },
|
||||
{ STR(LANG_CONTRAST), contrast },
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
{ str(LANG_INVERT), invert },
|
||||
{ str(LANG_FLIP_DISPLAY), flip_display },
|
||||
{ str(LANG_INVERT_CURSOR), invert_cursor },
|
||||
{ STR(LANG_INVERT), invert },
|
||||
{ STR(LANG_FLIP_DISPLAY), flip_display },
|
||||
{ STR(LANG_INVERT_CURSOR), invert_cursor },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -977,10 +977,10 @@ static bool bars_settings_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_SCROLL_BAR), scroll_bar },
|
||||
{ str(LANG_STATUS_BAR), status_bar },
|
||||
{ str(LANG_VOLUME_DISPLAY), volume_type },
|
||||
{ str(LANG_BATTERY_DISPLAY), battery_type },
|
||||
{ STR(LANG_SCROLL_BAR), scroll_bar },
|
||||
{ STR(LANG_STATUS_BAR), status_bar },
|
||||
{ STR(LANG_VOLUME_DISPLAY), volume_type },
|
||||
{ STR(LANG_BATTERY_DISPLAY), battery_type },
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
|
||||
|
|
@ -998,14 +998,14 @@ static bool display_settings_menu(void)
|
|||
|
||||
struct menu_items items[] = {
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
{ str(LANG_CUSTOM_FONT), font_browse },
|
||||
{ STR(LANG_CUSTOM_FONT), font_browse },
|
||||
#endif
|
||||
{ str(LANG_WHILE_PLAYING), custom_wps_browse },
|
||||
{ str(LANG_LCD_MENU), lcd_settings_menu },
|
||||
{ str(LANG_SCROLL_MENU), scroll_settings_menu },
|
||||
{ STR(LANG_WHILE_PLAYING), custom_wps_browse },
|
||||
{ STR(LANG_LCD_MENU), lcd_settings_menu },
|
||||
{ STR(LANG_SCROLL_MENU), scroll_settings_menu },
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
{ str(LANG_BARS_MENU), bars_settings_menu },
|
||||
{ str(LANG_PM_MENU), peak_meter_menu },
|
||||
{ STR(LANG_BARS_MENU), bars_settings_menu },
|
||||
{ STR(LANG_PM_MENU), peak_meter_menu },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -1028,11 +1028,11 @@ static bool battery_settings_menu(void)
|
|||
|
||||
struct menu_items items[] = {
|
||||
#ifdef HAVE_CHARGE_CTRL
|
||||
{ str(LANG_DISCHARGE), deep_discharge },
|
||||
{ str(LANG_TRICKLE_CHARGE), trickle_charge },
|
||||
{ STR(LANG_DISCHARGE), deep_discharge },
|
||||
{ STR(LANG_TRICKLE_CHARGE), trickle_charge },
|
||||
#endif
|
||||
#ifndef SIMULATOR
|
||||
{ str(LANG_BATTERY_CAPACITY), battery_capacity },
|
||||
{ STR(LANG_BATTERY_CAPACITY), battery_capacity },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -1048,9 +1048,9 @@ static bool disk_settings_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_SPINDOWN), spindown },
|
||||
{ STR(LANG_SPINDOWN), spindown },
|
||||
#ifdef HAVE_ATA_POWER_OFF
|
||||
{ str(LANG_POWEROFF), poweroff },
|
||||
{ STR(LANG_POWEROFF), poweroff },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -1067,8 +1067,8 @@ static bool time_settings_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_TIME), timedate_set },
|
||||
{ str(LANG_TIMEFORMAT), timeformat_set },
|
||||
{ STR(LANG_TIME), timedate_set },
|
||||
{ STR(LANG_TIMEFORMAT), timeformat_set },
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
|
||||
|
|
@ -1084,10 +1084,10 @@ static bool manage_settings_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_CUSTOM_CFG), custom_cfg_browse },
|
||||
{ str(LANG_FIRMWARE), firmware_browse },
|
||||
{ str(LANG_RESET), reset_settings },
|
||||
{ str(LANG_SAVE_SETTINGS), settings_save_config },
|
||||
{ STR(LANG_CUSTOM_CFG), custom_cfg_browse },
|
||||
{ STR(LANG_FIRMWARE), firmware_browse },
|
||||
{ STR(LANG_RESET), reset_settings },
|
||||
{ STR(LANG_SAVE_SETTINGS), settings_save_config },
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
|
||||
|
|
@ -1102,8 +1102,8 @@ static bool limits_settings_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_MAX_FILES_IN_DIR), max_files_in_dir },
|
||||
{ str(LANG_MAX_FILES_IN_PLAYLIST), max_files_in_playlist },
|
||||
{ STR(LANG_MAX_FILES_IN_DIR), max_files_in_dir },
|
||||
{ STR(LANG_MAX_FILES_IN_PLAYLIST), max_files_in_playlist },
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
|
||||
|
|
@ -1119,22 +1119,22 @@ static bool system_settings_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_BATTERY_MENU), battery_settings_menu },
|
||||
{ str(LANG_DISK_MENU), disk_settings_menu },
|
||||
{ STR(LANG_BATTERY_MENU), battery_settings_menu },
|
||||
{ STR(LANG_DISK_MENU), disk_settings_menu },
|
||||
#ifdef HAVE_RTC
|
||||
{ str(LANG_TIME_MENU), time_settings_menu },
|
||||
{ STR(LANG_TIME_MENU), time_settings_menu },
|
||||
#endif
|
||||
{ str(LANG_POWEROFF_IDLE), poweroff_idle_timer },
|
||||
{ str(LANG_SLEEP_TIMER), sleeptimer_screen },
|
||||
{ STR(LANG_POWEROFF_IDLE), poweroff_idle_timer },
|
||||
{ STR(LANG_SLEEP_TIMER), sleeptimer_screen },
|
||||
#ifdef HAVE_ALARM_MOD
|
||||
{ str(LANG_ALARM_MOD_ALARM_MENU), alarm_screen },
|
||||
{ STR(LANG_ALARM_MOD_ALARM_MENU), alarm_screen },
|
||||
#endif
|
||||
{ str(LANG_LIMITS_MENU), limits_settings_menu },
|
||||
{ STR(LANG_LIMITS_MENU), limits_settings_menu },
|
||||
#ifdef HAVE_MAS3507D
|
||||
{ str(LANG_LINE_IN), line_in },
|
||||
{ STR(LANG_LINE_IN), line_in },
|
||||
#endif
|
||||
{ str(LANG_CAR_ADAPTER_MODE), car_adapter_mode },
|
||||
{ str(LANG_MANAGE_MENU), manage_settings_menu },
|
||||
{ STR(LANG_CAR_ADAPTER_MODE), car_adapter_mode },
|
||||
{ STR(LANG_MANAGE_MENU), manage_settings_menu },
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
|
||||
|
|
@ -1149,12 +1149,12 @@ bool settings_menu(void)
|
|||
bool result;
|
||||
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_PLAYBACK), playback_settings_menu },
|
||||
{ str(LANG_FILE), fileview_settings_menu },
|
||||
{ str(LANG_DISPLAY), display_settings_menu },
|
||||
{ str(LANG_SYSTEM), system_settings_menu },
|
||||
{ str(LANG_BOOKMARK_SETTINGS),bookmark_settings_menu },
|
||||
{ str(LANG_LANGUAGE), language_browse },
|
||||
{ STR(LANG_PLAYBACK), playback_settings_menu },
|
||||
{ STR(LANG_FILE), fileview_settings_menu },
|
||||
{ STR(LANG_DISPLAY), display_settings_menu },
|
||||
{ STR(LANG_SYSTEM), system_settings_menu },
|
||||
{ STR(LANG_BOOKMARK_SETTINGS),bookmark_settings_menu },
|
||||
{ STR(LANG_LANGUAGE), language_browse },
|
||||
};
|
||||
|
||||
m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
|
||||
|
|
|
|||
|
|
@ -295,15 +295,15 @@ bool sound_menu(void)
|
|||
int m;
|
||||
bool result;
|
||||
struct menu_items items[] = {
|
||||
{ str(LANG_VOLUME), volume },
|
||||
{ str(LANG_BASS), bass },
|
||||
{ str(LANG_TREBLE), treble },
|
||||
{ str(LANG_BALANCE), balance },
|
||||
{ str(LANG_CHANNEL_MENU), chanconf },
|
||||
{ STR(LANG_VOLUME), volume },
|
||||
{ STR(LANG_BASS), bass },
|
||||
{ STR(LANG_TREBLE), treble },
|
||||
{ STR(LANG_BALANCE), balance },
|
||||
{ STR(LANG_CHANNEL_MENU), chanconf },
|
||||
#ifdef HAVE_MAS3587F
|
||||
{ str(LANG_LOUDNESS), loudness },
|
||||
{ str(LANG_BBOOST), bass_boost },
|
||||
{ str(LANG_AUTOVOL), avc }
|
||||
{ STR(LANG_LOUDNESS), loudness },
|
||||
{ STR(LANG_BBOOST), bass_boost },
|
||||
{ STR(LANG_AUTOVOL), avc }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -323,22 +323,30 @@ bool recording_menu(bool no_source)
|
|||
bool result;
|
||||
|
||||
menu[i].desc = str(LANG_RECORDING_QUALITY);
|
||||
menu[i].voice_id = LANG_RECORDING_QUALITY;
|
||||
menu[i++].function = recquality;
|
||||
menu[i].desc = str(LANG_RECORDING_FREQUENCY);
|
||||
menu[i].voice_id = LANG_RECORDING_FREQUENCY;
|
||||
menu[i++].function = recfrequency;
|
||||
if(!no_source) {
|
||||
menu[i].desc = str(LANG_RECORDING_SOURCE);
|
||||
menu[i].voice_id = LANG_RECORDING_SOURCE;
|
||||
menu[i++].function = recsource;
|
||||
}
|
||||
menu[i].desc = str(LANG_RECORDING_CHANNELS);
|
||||
menu[i].voice_id = LANG_RECORDING_CHANNELS;
|
||||
menu[i++].function = recchannels;
|
||||
menu[i].desc = str(LANG_RECORDING_EDITABLE);
|
||||
menu[i].voice_id = LANG_RECORDING_EDITABLE;
|
||||
menu[i++].function = receditable;
|
||||
menu[i].desc = str(LANG_RECORD_TIMESPLIT);
|
||||
menu[i].voice_id = LANG_RECORD_TIMESPLIT;
|
||||
menu[i++].function = rectimesplit;
|
||||
menu[i].desc = str(LANG_RECORD_PRERECORD_TIME);
|
||||
menu[i].voice_id = LANG_RECORD_PRERECORD_TIME;
|
||||
menu[i++].function = recprerecord;
|
||||
menu[i].desc = str(LANG_RECORD_DIRECTORY);
|
||||
menu[i].voice_id = LANG_RECORD_DIRECTORY;
|
||||
menu[i++].function = recdirectory;
|
||||
|
||||
m=menu_init( menu, i, NULL );
|
||||
|
|
|
|||
34
firmware/export/talk.h
Normal file
34
firmware/export/talk.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004 Jörg Hohensohn
|
||||
*
|
||||
* This module collects the Talkbox and voice UI functions.
|
||||
* (Talkbox reads directory names from mp3 clips called thumbnails,
|
||||
* the voice UI lets menus and screens "talk" from a voicefont in memory.
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __TALK_H__
|
||||
#define __TALK_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
void talk_init(void);
|
||||
int talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */
|
||||
int talk_id(int id, bool block); /* play a voice ID from voicefont */
|
||||
int talk_file(char* filename, bool block); /* play a thumbnail from file */
|
||||
|
||||
#endif /* __TALK_H__ */
|
||||
|
|
@ -2134,6 +2134,7 @@ void mpeg_record(char *filename)
|
|||
recording_filename[MAX_PATH - 1] = 0;
|
||||
|
||||
disable_xing_header = false;
|
||||
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
|
||||
queue_post(&mpeg_queue, MPEG_RECORD, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -2148,6 +2149,7 @@ static void start_prerecording(void)
|
|||
prerecord_timeout = current_tick + HZ;
|
||||
memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
|
||||
reset_mp3_buffer();
|
||||
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
|
||||
|
||||
is_prerecording = true;
|
||||
|
||||
|
|
@ -2404,6 +2406,7 @@ void mpeg_play(int offset)
|
|||
#else
|
||||
is_playing = true;
|
||||
|
||||
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
|
||||
queue_post(&mpeg_queue, MPEG_PLAY, (void*)offset);
|
||||
#endif /* #ifdef SIMULATOR */
|
||||
|
||||
|
|
|
|||
209
firmware/talk.c
Normal file
209
firmware/talk.c
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2004 Jörg Hohensohn
|
||||
*
|
||||
* This module collects the Talkbox and voice UI functions.
|
||||
* (Talkbox reads directory names from mp3 clips called thumbnails,
|
||||
* the voice UI lets menus and screens "talk" from a voicefont in memory.
|
||||
*
|
||||
* All files in this archive are subject to the GNU General Public License.
|
||||
* See the file COPYING in the source tree root for full license agreement.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include "file.h"
|
||||
#include "buffer.h"
|
||||
#include "kernel.h"
|
||||
#include "mp3_playback.h"
|
||||
#include "mpeg.h"
|
||||
#include "talk.h"
|
||||
extern void bitswap(unsigned char *data, int length); /* no header for this */
|
||||
|
||||
/***************** Constants *****************/
|
||||
|
||||
#define VOICEFONT_FILENAME "/.rockbox/voicefont"
|
||||
|
||||
|
||||
/***************** Data types *****************/
|
||||
|
||||
struct clip_entry /* one entry of the index table */
|
||||
{
|
||||
int offset; /* offset from start of voicefont file */
|
||||
int size; /* size of the clip */
|
||||
};
|
||||
|
||||
struct voicefont /* file format of our "voicefont" */
|
||||
{
|
||||
int version; /* version of the voicefont */
|
||||
int headersize; /* size of the header, =offset to index */
|
||||
int id_max; /* number of clips contained */
|
||||
struct clip_entry index[]; /* followed by the index table */
|
||||
/* and finally the bitswapped mp3 clips, not visible here */
|
||||
};
|
||||
|
||||
|
||||
/***************** Globals *****************/
|
||||
|
||||
static unsigned char* p_thumbnail; /* buffer for thumbnail */
|
||||
static long size_for_thumbnail; /* leftover buffer size for it */
|
||||
static struct voicefont* p_voicefont; /* loaded voicefont */
|
||||
static bool has_voicefont; /* a voicefont file is present */
|
||||
static bool is_playing; /* we're currently playing */
|
||||
|
||||
|
||||
|
||||
/***************** Private implementation *****************/
|
||||
|
||||
static int load_voicefont(void)
|
||||
{
|
||||
int fd;
|
||||
int size;
|
||||
|
||||
p_voicefont = NULL; /* indicate no voicefont if we fail below */
|
||||
|
||||
fd = open(VOICEFONT_FILENAME, O_RDONLY);
|
||||
if (fd < 0) /* failed to open */
|
||||
{
|
||||
p_voicefont = NULL; /* indicate no voicefont */
|
||||
has_voicefont = false; /* don't try again */
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = read(fd, mp3buf, mp3end - mp3buf);
|
||||
if (size > 1000
|
||||
&& ((struct voicefont*)mp3buf)->headersize
|
||||
== offsetof(struct voicefont, index))
|
||||
{
|
||||
p_voicefont = (struct voicefont*)mp3buf;
|
||||
|
||||
/* thumbnail buffer is the remaining space behind */
|
||||
p_thumbnail = mp3buf + size;
|
||||
p_thumbnail += (int)p_thumbnail % 2; /* 16-bit align */
|
||||
size_for_thumbnail = mp3end - p_thumbnail;
|
||||
|
||||
/* max. DMA size, fixme */
|
||||
if (size_for_thumbnail > 0xFFFF)
|
||||
size_for_thumbnail = 0xFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
has_voicefont = false; /* don't try again */
|
||||
}
|
||||
close(fd);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/* called in ISR context if mp3 data got consumed */
|
||||
void mp3_callback(unsigned char** start, int* size)
|
||||
{
|
||||
(void)start; /* unused parameter, avoid warning */
|
||||
*size = 0; /* end of data */
|
||||
is_playing = false;
|
||||
mp3_play_stop(); /* fixme: should be done by caller */
|
||||
}
|
||||
|
||||
/***************** Public implementation *****************/
|
||||
|
||||
void talk_init(void)
|
||||
{
|
||||
has_voicefont = true; /* unless we fail later, assume we have one */
|
||||
talk_buffer_steal();
|
||||
}
|
||||
|
||||
|
||||
/* somebody else claims the mp3 buffer, e.g. for regular play/record */
|
||||
int talk_buffer_steal(void)
|
||||
{
|
||||
p_voicefont = NULL; /* indicate no voicefont (trashed) */
|
||||
p_thumbnail = mp3buf; /* whole space for thumbnail */
|
||||
size_for_thumbnail = mp3end - mp3buf;
|
||||
/* max. DMA size, fixme */
|
||||
if (size_for_thumbnail > 0xFFFF)
|
||||
size_for_thumbnail = 0xFFFF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* play a voice ID from voicefont */
|
||||
int talk_id(int id, bool block)
|
||||
{
|
||||
int clipsize;
|
||||
|
||||
if (mpeg_status()) /* busy, buffer in use */
|
||||
return -1;
|
||||
|
||||
if (p_voicefont == NULL && has_voicefont)
|
||||
load_voicefont(); /* reload needed */
|
||||
|
||||
if (p_voicefont == NULL) /* still no voices? */
|
||||
return -1;
|
||||
|
||||
if (id >= p_voicefont->id_max)
|
||||
return -1;
|
||||
|
||||
clipsize = p_voicefont->index[id].size;
|
||||
if (clipsize == 0) /* clip not included in voicefont */
|
||||
return -1;
|
||||
|
||||
is_playing = true;
|
||||
mp3_play_data(mp3buf + p_voicefont->index[id].offset,
|
||||
clipsize, mp3_callback);
|
||||
mp3_play_pause(true); /* kickoff audio */
|
||||
|
||||
while(block && is_playing)
|
||||
sleep(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* play a thumbnail from file */
|
||||
int talk_file(char* filename, bool block)
|
||||
{
|
||||
int fd;
|
||||
int size;
|
||||
|
||||
if (mpeg_status()) /* busy, buffer in use */
|
||||
return -1;
|
||||
|
||||
if (p_thumbnail == NULL || size_for_thumbnail <= 0)
|
||||
return -1;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) /* failed to open */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size = read(fd, p_thumbnail, size_for_thumbnail);
|
||||
close(fd);
|
||||
|
||||
/* ToDo: find audio, skip ID headers and trailers */
|
||||
|
||||
if (size)
|
||||
{
|
||||
bitswap(p_thumbnail, size);
|
||||
is_playing = true;
|
||||
mp3_play_data(p_thumbnail, size, mp3_callback);
|
||||
mp3_play_pause(true); /* kickoff audio */
|
||||
|
||||
while(block && is_playing)
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
|
@ -225,3 +225,22 @@ void button_set_flip(bool yesno)
|
|||
{
|
||||
(void)yesno;
|
||||
}
|
||||
|
||||
int talk_buffer_steal(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int talk_id(int id, bool block)
|
||||
{
|
||||
(void)id;
|
||||
(void)block;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int talk_file(char* filename, bool block)
|
||||
{
|
||||
(void)filename;
|
||||
(void)block;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue