1
0
Fork 0
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:
Jörg Hohensohn 2004-03-14 21:33:53 +00:00
parent 62b095d029
commit 4f36ea8fbf
18 changed files with 454 additions and 122 deletions

View file

@ -93,9 +93,9 @@ bool bookmark_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_BOOKMARK_MENU_CREATE), bookmark_create_menu}, { STR(LANG_BOOKMARK_MENU_CREATE), bookmark_create_menu},
{ str(LANG_BOOKMARK_MENU_LIST), bookmark_load_menu}, { STR(LANG_BOOKMARK_MENU_LIST), bookmark_load_menu},
{ str(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS), bookmark_mrb_load}, { STR(LANG_BOOKMARK_MENU_RECENT_BOOKMARKS), bookmark_mrb_load},
}; };
m=menu_init( items, sizeof items / sizeof(struct menu_items), NULL ); m=menu_init( items, sizeof items / sizeof(struct menu_items), NULL );

View file

@ -1476,36 +1476,36 @@ bool debug_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ "Dump ROM contents", dbg_save_roms }, { "Dump ROM contents", -1, dbg_save_roms },
{ "View I/O ports", dbg_ports }, { "View I/O ports", -1, dbg_ports },
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
#ifdef HAVE_RTC #ifdef HAVE_RTC
{ "View/clr RTC RAM", dbg_rtc }, { "View/clr RTC RAM", -1, dbg_rtc },
#endif /* HAVE_RTC */ #endif /* HAVE_RTC */
#endif /* HAVE_LCD_BITMAP */ #endif /* HAVE_LCD_BITMAP */
{ "View OS stacks", dbg_os }, { "View OS stacks", -1, dbg_os },
#ifdef HAVE_MAS3507D #ifdef HAVE_MAS3507D
{ "View MAS info", dbg_mas_info }, { "View MAS info", -1, dbg_mas_info },
#endif #endif
{ "View MAS regs", dbg_mas }, { "View MAS regs", -1, dbg_mas },
#ifdef HAVE_MAS3587F #ifdef HAVE_MAS3587F
{ "View MAS codec", dbg_mas_codec }, { "View MAS codec", -1, dbg_mas_codec },
#endif #endif
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
{ "View battery", view_battery }, { "View battery", -1, view_battery },
#endif #endif
{ "View HW info", dbg_hw_info }, { "View HW info", -1, dbg_hw_info },
{ "View partitions", dbg_partitions }, { "View partitions", -1, dbg_partitions },
{ "View disk info", dbg_disk_info }, { "View disk info", -1, dbg_disk_info },
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
{ "View mpeg thread", dbg_mpeg_thread }, { "View mpeg thread", -1, dbg_mpeg_thread },
#ifdef PM_DEBUG #ifdef PM_DEBUG
{ "pm histogram", peak_meter_histogram}, { "pm histogram", -1, peak_meter_histogram},
#endif /* PM_DEBUG */ #endif /* PM_DEBUG */
#endif /* HAVE_LCD_BITMAP */ #endif /* HAVE_LCD_BITMAP */
{ "View runtime", view_runtime }, { "View runtime", -1, view_runtime },
#ifdef HAVE_FMRADIO #ifdef HAVE_FMRADIO
{ "FM Radio", dbg_fm_radio }, { "FM Radio", -1, dbg_fm_radio },
#endif #endif
}; };

View file

@ -54,6 +54,7 @@
#include "rolo.h" #include "rolo.h"
#include "screens.h" #include "screens.h"
#include "power.h" #include "power.h"
#include "talk.h"
char appsversion[]=APPSVERSION; char appsversion[]=APPSVERSION;
@ -208,6 +209,7 @@ void init(void)
global_settings.avc, global_settings.avc,
global_settings.channel_config ); global_settings.channel_config );
mpeg_init(); mpeg_init();
talk_init();
/* no auto-rolo on startup any more, but I leave it here for reference */ /* no auto-rolo on startup any more, but I leave it here for reference */
#if 0 #if 0

View file

@ -262,8 +262,8 @@ bool rec_menu(void)
/* recording menu */ /* recording menu */
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_RECORDING_MENU), recording_screen }, { STR(LANG_RECORDING_MENU), recording_screen },
{ str(LANG_RECORDING_SETTINGS), recording_settings}, { STR(LANG_RECORDING_SETTINGS), recording_settings},
}; };
m=menu_init( items, sizeof items / sizeof(struct menu_items), NULL ); m=menu_init( items, sizeof items / sizeof(struct menu_items), NULL );
@ -281,13 +281,13 @@ bool info_menu(void)
/* info menu */ /* info menu */
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_MENU_SHOW_ID3_INFO), browse_id3 }, { STR(LANG_MENU_SHOW_ID3_INFO), browse_id3 },
{ str(LANG_INFO_MENU), show_info }, { STR(LANG_INFO_MENU), show_info },
{ str(LANG_VERSION), show_credits }, { STR(LANG_VERSION), show_credits },
#ifndef SIMULATOR #ifndef SIMULATOR
{ str(LANG_DEBUG), debug_menu }, { STR(LANG_DEBUG), debug_menu },
#else #else
{ str(LANG_USB), simulate_usb }, { STR(LANG_USB), simulate_usb },
#endif #endif
}; };
@ -308,33 +308,41 @@ bool main_menu(void)
struct menu_items items[8]; struct menu_items items[8];
items[i].desc = str(LANG_BOOKMARK_MENU); items[i].desc = str(LANG_BOOKMARK_MENU);
items[i].voice_id = LANG_BOOKMARK_MENU;
items[i++].function = bookmark_menu; items[i++].function = bookmark_menu;
items[i].desc = str(LANG_SOUND_SETTINGS); items[i].desc = str(LANG_SOUND_SETTINGS);
items[i].voice_id = LANG_SOUND_SETTINGS;
items[i++].function = sound_menu; items[i++].function = sound_menu;
items[i].desc = str(LANG_GENERAL_SETTINGS); items[i].desc = str(LANG_GENERAL_SETTINGS);
items[i].voice_id = LANG_GENERAL_SETTINGS;
items[i++].function = settings_menu; items[i++].function = settings_menu;
#ifdef HAVE_FMRADIO #ifdef HAVE_FMRADIO
if(radio_hardware_present()) { if(radio_hardware_present()) {
items[i].desc = str(LANG_FM_RADIO); items[i].desc = str(LANG_FM_RADIO);
items[i].voice_id = LANG_FM_RADIO;
items[i++].function = radio_screen; items[i++].function = radio_screen;
} }
#endif #endif
#ifdef HAVE_MAS3587F #ifdef HAVE_MAS3587F
items[i].desc = str(LANG_RECORDING); items[i].desc = str(LANG_RECORDING);
items[i].voice_id = LANG_RECORDING;
items[i++].function = rec_menu; items[i++].function = rec_menu;
#endif #endif
items[i].desc = str(LANG_PLAYLIST_MENU); items[i].desc = str(LANG_PLAYLIST_MENU);
items[i].voice_id = LANG_PLAYLIST_MENU;
items[i++].function = playlist_menu; items[i++].function = playlist_menu;
items[i].desc = str(LANG_PLUGINS); items[i].desc = str(LANG_PLUGINS);
items[i].voice_id = LANG_PLUGINS;
items[i++].function = plugin_browse; items[i++].function = plugin_browse;
items[i].desc = str(LANG_INFO); items[i].desc = str(LANG_INFO);
items[i].voice_id = LANG_INFO;
items[i++].function = info_menu; items[i++].function = info_menu;
m=menu_init( items, i, NULL ); m=menu_init( items, i, NULL );

View file

@ -32,6 +32,7 @@
#include "settings.h" #include "settings.h"
#include "status.h" #include "status.h"
#include "screens.h" #include "screens.h"
#include "talk.h"
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
#include "icons.h" #include "icons.h"
@ -216,6 +217,13 @@ static void put_cursor(int m, int target)
lcd_update(); 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)) 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; bool exit = false;
int key; int key;
int voice_id;
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
int fw, fh; int fw, fh;
int menu_lines; int menu_lines;
@ -263,9 +272,16 @@ int menu_show(int m)
menu_draw(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) { while (!exit) {
key = button_get_w_tmo(HZ/2); key = button_get_w_tmo(HZ/2);
/* /*
* "short-circuit" the default keypresses by running the callback function * "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 */ key = menus[m].callback(key, m); /* make sure there's no match in the switch */
switch( key ) { switch( key ) {
#ifdef HAVE_RECORDER_KEYPAD #ifdef HAVE_RECORDER_KEYPAD
case BUTTON_UP: case BUTTON_UP:
case BUTTON_UP | BUTTON_REPEAT: case BUTTON_UP | BUTTON_REPEAT:

View file

@ -23,10 +23,14 @@
#include <stdbool.h> #include <stdbool.h>
struct menu_items { 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 */ 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)); int menu_init(struct menu_items* items, int count, int (*callback) (int keycode, int menu));
void menu_exit(int menu); void menu_exit(int menu);

View file

@ -41,6 +41,7 @@
#include "settings.h" #include "settings.h"
#include "status.h" #include "status.h"
#include "playlist_viewer.h" #include "playlist_viewer.h"
#include "talk.h"
#include "onplay.h" #include "onplay.h"
static char* selected_file = NULL; static char* selected_file = NULL;
@ -147,6 +148,7 @@ static bool playlist_options(void)
if ((selected_file_attr & TREE_ATTR_MASK) == TREE_ATTR_M3U) if ((selected_file_attr & TREE_ATTR_MASK) == TREE_ATTR_M3U)
{ {
menu[i].desc = str(LANG_VIEW); menu[i].desc = str(LANG_VIEW);
menu[i].voice_id = LANG_VIEW;
menu[i].function = view_playlist; menu[i].function = view_playlist;
i++; i++;
pstart++; pstart++;
@ -155,31 +157,37 @@ static bool playlist_options(void)
if (mpeg_status() & MPEG_STATUS_PLAY) if (mpeg_status() & MPEG_STATUS_PLAY)
{ {
menu[i].desc = str(LANG_INSERT); menu[i].desc = str(LANG_INSERT);
menu[i].voice_id = LANG_INSERT;
args[i].position = PLAYLIST_INSERT; args[i].position = PLAYLIST_INSERT;
args[i].queue = false; args[i].queue = false;
i++; i++;
menu[i].desc = str(LANG_INSERT_FIRST); menu[i].desc = str(LANG_INSERT_FIRST);
menu[i].voice_id = LANG_INSERT_FIRST;
args[i].position = PLAYLIST_INSERT_FIRST; args[i].position = PLAYLIST_INSERT_FIRST;
args[i].queue = false; args[i].queue = false;
i++; i++;
menu[i].desc = str(LANG_INSERT_LAST); menu[i].desc = str(LANG_INSERT_LAST);
menu[i].voice_id = LANG_INSERT_LAST;
args[i].position = PLAYLIST_INSERT_LAST; args[i].position = PLAYLIST_INSERT_LAST;
args[i].queue = false; args[i].queue = false;
i++; i++;
menu[i].desc = str(LANG_QUEUE); menu[i].desc = str(LANG_QUEUE);
menu[i].voice_id = LANG_QUEUE;
args[i].position = PLAYLIST_INSERT; args[i].position = PLAYLIST_INSERT;
args[i].queue = true; args[i].queue = true;
i++; i++;
menu[i].desc = str(LANG_QUEUE_FIRST); menu[i].desc = str(LANG_QUEUE_FIRST);
menu[i].voice_id = LANG_QUEUE_FIRST;
args[i].position = PLAYLIST_INSERT_FIRST; args[i].position = PLAYLIST_INSERT_FIRST;
args[i].queue = true; args[i].queue = true;
i++; i++;
menu[i].desc = str(LANG_QUEUE_LAST); menu[i].desc = str(LANG_QUEUE_LAST);
menu[i].voice_id = LANG_QUEUE_LAST;
args[i].position = PLAYLIST_INSERT_LAST; args[i].position = PLAYLIST_INSERT_LAST;
args[i].queue = true; args[i].queue = true;
i++; i++;
@ -188,6 +196,7 @@ static bool playlist_options(void)
(selected_file_attr & ATTR_DIRECTORY)) (selected_file_attr & ATTR_DIRECTORY))
{ {
menu[i].desc = str(LANG_INSERT); menu[i].desc = str(LANG_INSERT);
menu[i].voice_id = LANG_INSERT;
args[i].position = PLAYLIST_INSERT; args[i].position = PLAYLIST_INSERT;
args[i].queue = false; args[i].queue = false;
i++; i++;
@ -283,6 +292,8 @@ static int insert_data_in_file(char *fname, int fpos, char *buf, int num_bytes)
int orig_fd, fd; int orig_fd, fd;
char tmpname[MAX_PATH]; char tmpname[MAX_PATH];
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
snprintf(tmpname, MAX_PATH, "%s.tmp", fname); snprintf(tmpname, MAX_PATH, "%s.tmp", fname);
orig_fd = open(fname, O_RDONLY); orig_fd = open(fname, O_RDONLY);
@ -384,6 +395,8 @@ static bool vbr_fix(void)
return onplay_result; return onplay_result;
} }
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
lcd_clear_display(); lcd_clear_display();
lcd_puts_scroll(0, 0, selected_file); lcd_puts_scroll(0, 0, selected_file);
lcd_update(); lcd_update();
@ -552,17 +565,20 @@ int onplay(char* file, int attr)
((attr & TREE_ATTR_MASK) == TREE_ATTR_M3U)) ((attr & TREE_ATTR_MASK) == TREE_ATTR_M3U))
{ {
menu[i].desc = str(LANG_PLAYINDICES_PLAYLIST); menu[i].desc = str(LANG_PLAYINDICES_PLAYLIST);
menu[i].voice_id = LANG_PLAYINDICES_PLAYLIST;
menu[i].function = playlist_options; menu[i].function = playlist_options;
i++; i++;
} }
menu[i].desc = str(LANG_RENAME); menu[i].desc = str(LANG_RENAME);
menu[i].voice_id = LANG_RENAME;
menu[i].function = rename_file; menu[i].function = rename_file;
i++; i++;
if (!(attr & ATTR_DIRECTORY)) if (!(attr & ATTR_DIRECTORY))
{ {
menu[i].desc = str(LANG_DELETE); menu[i].desc = str(LANG_DELETE);
menu[i].voice_id = LANG_DELETE;
menu[i].function = delete_file; menu[i].function = delete_file;
i++; i++;
} }
@ -570,12 +586,14 @@ int onplay(char* file, int attr)
if ((attr & TREE_ATTR_MASK) == TREE_ATTR_MPA) if ((attr & TREE_ATTR_MASK) == TREE_ATTR_MPA)
{ {
menu[i].desc = str(LANG_VBRFIX); menu[i].desc = str(LANG_VBRFIX);
menu[i].voice_id = LANG_VBRFIX;
menu[i].function = vbr_fix; menu[i].function = vbr_fix;
i++; i++;
} }
} }
menu[i].desc = str(LANG_CREATE_DIR); menu[i].desc = str(LANG_CREATE_DIR);
menu[i].voice_id = LANG_CREATE_DIR;
menu[i].function = create_dir; menu[i].function = create_dir;
i++; i++;

View file

@ -91,6 +91,7 @@
#endif #endif
#include "lang.h" #include "lang.h"
#include "talk.h"
#define PLAYLIST_CONTROL_FILE ROCKBOX_DIR "/.playlist_control" #define PLAYLIST_CONTROL_FILE ROCKBOX_DIR "/.playlist_control"
#define PLAYLIST_CONTROL_FILE_VERSION 2 #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 */ /* use mp3 buffer for maximum load speed */
mpeg_stop(); mpeg_stop();
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
buffer = mp3buf; buffer = mp3buf;
buflen = (mp3end - mp3buf); buflen = (mp3end - mp3buf);
@ -1192,6 +1194,7 @@ int playlist_resume(void)
}; };
/* use mp3 buffer for maximum load speed */ /* use mp3 buffer for maximum load speed */
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
buflen = (mp3end - mp3buf); buflen = (mp3end - mp3buf);
buffer = mp3buf; buffer = mp3buf;

View file

@ -65,10 +65,10 @@ bool playlist_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_CREATE_PLAYLIST), create_playlist }, { STR(LANG_CREATE_PLAYLIST), create_playlist },
{ str(LANG_VIEW_DYNAMIC_PLAYLIST), playlist_viewer }, { STR(LANG_VIEW_DYNAMIC_PLAYLIST), playlist_viewer },
{ str(LANG_SAVE_DYNAMIC_PLAYLIST), save_playlist }, { STR(LANG_SAVE_DYNAMIC_PLAYLIST), save_playlist },
{ str(LANG_RECURSE_DIRECTORY), recurse_directory }, { STR(LANG_RECURSE_DIRECTORY), recurse_directory },
}; };
m = menu_init( items, sizeof items / sizeof(struct menu_items), NULL ); m = menu_init( items, sizeof items / sizeof(struct menu_items), NULL );

View file

@ -685,12 +685,15 @@ static int onplay_menu(int index)
bool current = (tracks[index].index == viewer.current_playing_track); bool current = (tracks[index].index == viewer.current_playing_track);
menu[i].desc = str(LANG_REMOVE); menu[i].desc = str(LANG_REMOVE);
menu[i].voice_id = LANG_REMOVE;
i++; i++;
menu[i].desc = str(LANG_MOVE); menu[i].desc = str(LANG_MOVE);
menu[i].voice_id = LANG_MOVE;
i++; i++;
menu[i].desc = str(LANG_FILE_OPTIONS); menu[i].desc = str(LANG_FILE_OPTIONS);
menu[i].voice_id = LANG_FILE_OPTIONS;
i++; i++;
m = menu_init(menu, i, NULL); m = menu_init(menu, i, NULL);
@ -757,10 +760,10 @@ static bool viewer_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_SHOW_ICONS), show_icons }, { STR(LANG_SHOW_ICONS), show_icons },
{ str(LANG_SHOW_INDICES), show_indices }, { STR(LANG_SHOW_INDICES), show_indices },
{ str(LANG_TRACK_DISPLAY), track_display }, { STR(LANG_TRACK_DISPLAY), track_display },
{ str(LANG_SAVE_DYNAMIC_PLAYLIST), save_playlist }, { STR(LANG_SAVE_DYNAMIC_PLAYLIST), save_playlist },
}; };
m=menu_init( items, sizeof(items) / sizeof(*items), NULL ); m=menu_init( items, sizeof(items) / sizeof(*items), NULL );

View file

@ -38,6 +38,7 @@
#include "mp3_playback.h" #include "mp3_playback.h"
#include "backlight.h" #include "backlight.h"
#include "ata.h" #include "ata.h"
#include "talk.h"
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
#include "widgets.h" #include "widgets.h"
@ -325,6 +326,7 @@ void* plugin_get_mp3_buffer(int* buffer_size)
return buf; return buf;
#else #else
mpeg_stop(); mpeg_stop();
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
*buffer_size = mp3end - mp3buf; *buffer_size = mp3end - mp3buf;
return mp3buf; return mp3buf;
#endif #endif

View file

@ -595,6 +595,7 @@ bool radio_preset_select(void)
if(presets[i].frequency) if(presets[i].frequency)
{ {
menu[num_presets].desc = presets[i].name; menu[num_presets].desc = presets[i].name;
menu[num_presets].voice_id = -1;
/* We use the function pointer entry for the preset /* We use the function pointer entry for the preset
entry index */ entry index */
menu[num_presets++].function = (void *)i; menu[num_presets++].function = (void *)i;
@ -669,6 +670,7 @@ bool radio_delete_preset(void)
if(presets[i].frequency) if(presets[i].frequency)
{ {
menu[num_presets].desc = presets[i].name; menu[num_presets].desc = presets[i].name;
menu[num_presets].voice_id = -1;
/* We use the function pointer entry for the preset /* We use the function pointer entry for the preset
entry index */ entry index */
menu[num_presets++].function = (void *)i; menu[num_presets++].function = (void *)i;
@ -715,10 +717,10 @@ static bool fm_recording_settings(void)
bool radio_menu(void) bool radio_menu(void)
{ {
struct menu_items radio_menu_items[] = { struct menu_items radio_menu_items[] = {
{ str(LANG_FM_SAVE_PRESET), radio_add_preset }, { STR(LANG_FM_SAVE_PRESET), radio_add_preset },
{ str(LANG_FM_DELETE_PRESET), radio_delete_preset }, { STR(LANG_FM_DELETE_PRESET), radio_delete_preset },
{ str(LANG_SOUND_SETTINGS), sound_menu }, { STR(LANG_SOUND_SETTINGS), sound_menu },
{ str(LANG_RECORDING_SETTINGS), fm_recording_settings } { STR(LANG_RECORDING_SETTINGS), fm_recording_settings }
}; };
int m; int m;
bool result; bool result;

View file

@ -368,16 +368,16 @@ static bool peak_meter_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_PM_RELEASE) , peak_meter_release }, { STR(LANG_PM_RELEASE) , peak_meter_release },
{ str(LANG_PM_PEAK_HOLD), peak_meter_hold }, { STR(LANG_PM_PEAK_HOLD), peak_meter_hold },
{ str(LANG_PM_CLIP_HOLD), peak_meter_clip_hold }, { STR(LANG_PM_CLIP_HOLD), peak_meter_clip_hold },
{ str(LANG_PM_PERFORMANCE), peak_meter_performance }, { STR(LANG_PM_PERFORMANCE), peak_meter_performance },
#ifdef PM_DEBUG #ifdef PM_DEBUG
{ "Refresh rate" , peak_meter_fps_menu }, { "Refresh rate" , -1 , peak_meter_fps_menu },
#endif #endif
{ str(LANG_PM_SCALE) , peak_meter_scale }, { STR(LANG_PM_SCALE) , peak_meter_scale },
{ str(LANG_PM_MIN) , peak_meter_min }, { STR(LANG_PM_MIN) , peak_meter_min },
{ str(LANG_PM_MAX) , peak_meter_max }, { STR(LANG_PM_MAX) , peak_meter_max },
}; };
m=menu_init( items, sizeof(items) / sizeof(*items), NULL ); m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
@ -791,8 +791,8 @@ static bool ff_rewind_settings_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_FFRW_STEP), ff_rewind_min_step }, { STR(LANG_FFRW_STEP), ff_rewind_min_step },
{ str(LANG_FFRW_ACCEL), ff_rewind_accel }, { STR(LANG_FFRW_ACCEL), ff_rewind_accel },
}; };
m=menu_init( items, sizeof(items) / sizeof(*items), NULL ); m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
@ -808,13 +808,13 @@ static bool playback_settings_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_SHUFFLE), shuffle }, { STR(LANG_SHUFFLE), shuffle },
{ str(LANG_REPEAT), repeat_mode }, { STR(LANG_REPEAT), repeat_mode },
{ str(LANG_PLAY_SELECTED), play_selected }, { STR(LANG_PLAY_SELECTED), play_selected },
{ str(LANG_RESUME), resume }, { STR(LANG_RESUME), resume },
{ str(LANG_WIND_MENU), ff_rewind_settings_menu }, { STR(LANG_WIND_MENU), ff_rewind_settings_menu },
{ str(LANG_MP3BUFFER_MARGIN), buffer_margin }, { STR(LANG_MP3BUFFER_MARGIN), buffer_margin },
{ str(LANG_FADE_ON_STOP), set_fade_on_stop }, { STR(LANG_FADE_ON_STOP), set_fade_on_stop },
}; };
bool old_shuffle = global_settings.playlist_shuffle; bool old_shuffle = global_settings.playlist_shuffle;
@ -843,9 +843,9 @@ static bool bookmark_settings_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_BOOKMARK_SETTINGS_AUTOCREATE), autocreatebookmark}, { STR(LANG_BOOKMARK_SETTINGS_AUTOCREATE), autocreatebookmark},
{ str(LANG_BOOKMARK_SETTINGS_AUTOLOAD), autoloadbookmark}, { STR(LANG_BOOKMARK_SETTINGS_AUTOLOAD), autoloadbookmark},
{ str(LANG_BOOKMARK_SETTINGS_MAINTAIN_RECENT_BOOKMARKS), useMRB}, { STR(LANG_BOOKMARK_SETTINGS_MAINTAIN_RECENT_BOOKMARKS), useMRB},
}; };
m=menu_init( items, sizeof items / sizeof(struct menu_items), NULL ); m=menu_init( items, sizeof items / sizeof(struct menu_items), NULL );
@ -910,10 +910,10 @@ static bool fileview_settings_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_CASE_MENU), sort_case }, { STR(LANG_CASE_MENU), sort_case },
{ str(LANG_FILTER), dir_filter }, { STR(LANG_FILTER), dir_filter },
{ str(LANG_FOLLOW), browse_current }, { STR(LANG_FOLLOW), browse_current },
{ str(LANG_SHOW_ICONS), show_icons }, { STR(LANG_SHOW_ICONS), show_icons },
}; };
m=menu_init( items, sizeof(items) / sizeof(*items), NULL ); m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
@ -929,15 +929,15 @@ static bool scroll_settings_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_SCROLL_SPEED), scroll_speed }, { STR(LANG_SCROLL_SPEED), scroll_speed },
{ str(LANG_SCROLL_DELAY), scroll_delay }, { STR(LANG_SCROLL_DELAY), scroll_delay },
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
{ str(LANG_SCROLL_STEP), scroll_step }, { STR(LANG_SCROLL_STEP), scroll_step },
#endif #endif
{ str(LANG_BIDIR_SCROLL), bidir_limit }, { STR(LANG_BIDIR_SCROLL), bidir_limit },
#ifdef HAVE_LCD_CHARCELLS #ifdef HAVE_LCD_CHARCELLS
{ str(LANG_JUMP_SCROLL), jump_scroll }, { STR(LANG_JUMP_SCROLL), jump_scroll },
{ str(LANG_JUMP_SCROLL_DELAY), jump_scroll_delay }, { STR(LANG_JUMP_SCROLL_DELAY), jump_scroll_delay },
#endif #endif
}; };
@ -953,14 +953,14 @@ static bool lcd_settings_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_BACKLIGHT), backlight_timer }, { STR(LANG_BACKLIGHT), backlight_timer },
{ str(LANG_BACKLIGHT_ON_WHEN_CHARGING), backlight_on_when_charging }, { STR(LANG_BACKLIGHT_ON_WHEN_CHARGING), backlight_on_when_charging },
{ str(LANG_CAPTION_BACKLIGHT), caption_backlight }, { STR(LANG_CAPTION_BACKLIGHT), caption_backlight },
{ str(LANG_CONTRAST), contrast }, { STR(LANG_CONTRAST), contrast },
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
{ str(LANG_INVERT), invert }, { STR(LANG_INVERT), invert },
{ str(LANG_FLIP_DISPLAY), flip_display }, { STR(LANG_FLIP_DISPLAY), flip_display },
{ str(LANG_INVERT_CURSOR), invert_cursor }, { STR(LANG_INVERT_CURSOR), invert_cursor },
#endif #endif
}; };
@ -977,10 +977,10 @@ static bool bars_settings_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_SCROLL_BAR), scroll_bar }, { STR(LANG_SCROLL_BAR), scroll_bar },
{ str(LANG_STATUS_BAR), status_bar }, { STR(LANG_STATUS_BAR), status_bar },
{ str(LANG_VOLUME_DISPLAY), volume_type }, { STR(LANG_VOLUME_DISPLAY), volume_type },
{ str(LANG_BATTERY_DISPLAY), battery_type }, { STR(LANG_BATTERY_DISPLAY), battery_type },
}; };
m=menu_init( items, sizeof(items) / sizeof(*items), NULL ); m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
@ -998,14 +998,14 @@ static bool display_settings_menu(void)
struct menu_items items[] = { struct menu_items items[] = {
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
{ str(LANG_CUSTOM_FONT), font_browse }, { STR(LANG_CUSTOM_FONT), font_browse },
#endif #endif
{ str(LANG_WHILE_PLAYING), custom_wps_browse }, { STR(LANG_WHILE_PLAYING), custom_wps_browse },
{ str(LANG_LCD_MENU), lcd_settings_menu }, { STR(LANG_LCD_MENU), lcd_settings_menu },
{ str(LANG_SCROLL_MENU), scroll_settings_menu }, { STR(LANG_SCROLL_MENU), scroll_settings_menu },
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
{ str(LANG_BARS_MENU), bars_settings_menu }, { STR(LANG_BARS_MENU), bars_settings_menu },
{ str(LANG_PM_MENU), peak_meter_menu }, { STR(LANG_PM_MENU), peak_meter_menu },
#endif #endif
}; };
@ -1028,11 +1028,11 @@ static bool battery_settings_menu(void)
struct menu_items items[] = { struct menu_items items[] = {
#ifdef HAVE_CHARGE_CTRL #ifdef HAVE_CHARGE_CTRL
{ str(LANG_DISCHARGE), deep_discharge }, { STR(LANG_DISCHARGE), deep_discharge },
{ str(LANG_TRICKLE_CHARGE), trickle_charge }, { STR(LANG_TRICKLE_CHARGE), trickle_charge },
#endif #endif
#ifndef SIMULATOR #ifndef SIMULATOR
{ str(LANG_BATTERY_CAPACITY), battery_capacity }, { STR(LANG_BATTERY_CAPACITY), battery_capacity },
#endif #endif
}; };
@ -1048,9 +1048,9 @@ static bool disk_settings_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_SPINDOWN), spindown }, { STR(LANG_SPINDOWN), spindown },
#ifdef HAVE_ATA_POWER_OFF #ifdef HAVE_ATA_POWER_OFF
{ str(LANG_POWEROFF), poweroff }, { STR(LANG_POWEROFF), poweroff },
#endif #endif
}; };
@ -1067,8 +1067,8 @@ static bool time_settings_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_TIME), timedate_set }, { STR(LANG_TIME), timedate_set },
{ str(LANG_TIMEFORMAT), timeformat_set }, { STR(LANG_TIMEFORMAT), timeformat_set },
}; };
m=menu_init( items, sizeof(items) / sizeof(*items), NULL ); m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
@ -1084,10 +1084,10 @@ static bool manage_settings_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_CUSTOM_CFG), custom_cfg_browse }, { STR(LANG_CUSTOM_CFG), custom_cfg_browse },
{ str(LANG_FIRMWARE), firmware_browse }, { STR(LANG_FIRMWARE), firmware_browse },
{ str(LANG_RESET), reset_settings }, { STR(LANG_RESET), reset_settings },
{ str(LANG_SAVE_SETTINGS), settings_save_config }, { STR(LANG_SAVE_SETTINGS), settings_save_config },
}; };
m=menu_init( items, sizeof(items) / sizeof(*items), NULL ); m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
@ -1102,8 +1102,8 @@ static bool limits_settings_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_MAX_FILES_IN_DIR), max_files_in_dir }, { 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_PLAYLIST), max_files_in_playlist },
}; };
m=menu_init( items, sizeof(items) / sizeof(*items), NULL ); m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
@ -1119,22 +1119,22 @@ static bool system_settings_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_BATTERY_MENU), battery_settings_menu }, { STR(LANG_BATTERY_MENU), battery_settings_menu },
{ str(LANG_DISK_MENU), disk_settings_menu }, { STR(LANG_DISK_MENU), disk_settings_menu },
#ifdef HAVE_RTC #ifdef HAVE_RTC
{ str(LANG_TIME_MENU), time_settings_menu }, { STR(LANG_TIME_MENU), time_settings_menu },
#endif #endif
{ str(LANG_POWEROFF_IDLE), poweroff_idle_timer }, { STR(LANG_POWEROFF_IDLE), poweroff_idle_timer },
{ str(LANG_SLEEP_TIMER), sleeptimer_screen }, { STR(LANG_SLEEP_TIMER), sleeptimer_screen },
#ifdef HAVE_ALARM_MOD #ifdef HAVE_ALARM_MOD
{ str(LANG_ALARM_MOD_ALARM_MENU), alarm_screen }, { STR(LANG_ALARM_MOD_ALARM_MENU), alarm_screen },
#endif #endif
{ str(LANG_LIMITS_MENU), limits_settings_menu }, { STR(LANG_LIMITS_MENU), limits_settings_menu },
#ifdef HAVE_MAS3507D #ifdef HAVE_MAS3507D
{ str(LANG_LINE_IN), line_in }, { STR(LANG_LINE_IN), line_in },
#endif #endif
{ str(LANG_CAR_ADAPTER_MODE), car_adapter_mode }, { STR(LANG_CAR_ADAPTER_MODE), car_adapter_mode },
{ str(LANG_MANAGE_MENU), manage_settings_menu }, { STR(LANG_MANAGE_MENU), manage_settings_menu },
}; };
m=menu_init( items, sizeof(items) / sizeof(*items), NULL ); m=menu_init( items, sizeof(items) / sizeof(*items), NULL );
@ -1149,12 +1149,12 @@ bool settings_menu(void)
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_PLAYBACK), playback_settings_menu }, { STR(LANG_PLAYBACK), playback_settings_menu },
{ str(LANG_FILE), fileview_settings_menu }, { STR(LANG_FILE), fileview_settings_menu },
{ str(LANG_DISPLAY), display_settings_menu }, { STR(LANG_DISPLAY), display_settings_menu },
{ str(LANG_SYSTEM), system_settings_menu }, { STR(LANG_SYSTEM), system_settings_menu },
{ str(LANG_BOOKMARK_SETTINGS),bookmark_settings_menu }, { STR(LANG_BOOKMARK_SETTINGS),bookmark_settings_menu },
{ str(LANG_LANGUAGE), language_browse }, { STR(LANG_LANGUAGE), language_browse },
}; };
m=menu_init( items, sizeof(items) / sizeof(*items), NULL ); m=menu_init( items, sizeof(items) / sizeof(*items), NULL );

View file

@ -295,15 +295,15 @@ bool sound_menu(void)
int m; int m;
bool result; bool result;
struct menu_items items[] = { struct menu_items items[] = {
{ str(LANG_VOLUME), volume }, { STR(LANG_VOLUME), volume },
{ str(LANG_BASS), bass }, { STR(LANG_BASS), bass },
{ str(LANG_TREBLE), treble }, { STR(LANG_TREBLE), treble },
{ str(LANG_BALANCE), balance }, { STR(LANG_BALANCE), balance },
{ str(LANG_CHANNEL_MENU), chanconf }, { STR(LANG_CHANNEL_MENU), chanconf },
#ifdef HAVE_MAS3587F #ifdef HAVE_MAS3587F
{ str(LANG_LOUDNESS), loudness }, { STR(LANG_LOUDNESS), loudness },
{ str(LANG_BBOOST), bass_boost }, { STR(LANG_BBOOST), bass_boost },
{ str(LANG_AUTOVOL), avc } { STR(LANG_AUTOVOL), avc }
#endif #endif
}; };
@ -323,22 +323,30 @@ bool recording_menu(bool no_source)
bool result; bool result;
menu[i].desc = str(LANG_RECORDING_QUALITY); menu[i].desc = str(LANG_RECORDING_QUALITY);
menu[i].voice_id = LANG_RECORDING_QUALITY;
menu[i++].function = recquality; menu[i++].function = recquality;
menu[i].desc = str(LANG_RECORDING_FREQUENCY); menu[i].desc = str(LANG_RECORDING_FREQUENCY);
menu[i].voice_id = LANG_RECORDING_FREQUENCY;
menu[i++].function = recfrequency; menu[i++].function = recfrequency;
if(!no_source) { if(!no_source) {
menu[i].desc = str(LANG_RECORDING_SOURCE); menu[i].desc = str(LANG_RECORDING_SOURCE);
menu[i].voice_id = LANG_RECORDING_SOURCE;
menu[i++].function = recsource; menu[i++].function = recsource;
} }
menu[i].desc = str(LANG_RECORDING_CHANNELS); menu[i].desc = str(LANG_RECORDING_CHANNELS);
menu[i].voice_id = LANG_RECORDING_CHANNELS;
menu[i++].function = recchannels; menu[i++].function = recchannels;
menu[i].desc = str(LANG_RECORDING_EDITABLE); menu[i].desc = str(LANG_RECORDING_EDITABLE);
menu[i].voice_id = LANG_RECORDING_EDITABLE;
menu[i++].function = receditable; menu[i++].function = receditable;
menu[i].desc = str(LANG_RECORD_TIMESPLIT); menu[i].desc = str(LANG_RECORD_TIMESPLIT);
menu[i].voice_id = LANG_RECORD_TIMESPLIT;
menu[i++].function = rectimesplit; menu[i++].function = rectimesplit;
menu[i].desc = str(LANG_RECORD_PRERECORD_TIME); menu[i].desc = str(LANG_RECORD_PRERECORD_TIME);
menu[i].voice_id = LANG_RECORD_PRERECORD_TIME;
menu[i++].function = recprerecord; menu[i++].function = recprerecord;
menu[i].desc = str(LANG_RECORD_DIRECTORY); menu[i].desc = str(LANG_RECORD_DIRECTORY);
menu[i].voice_id = LANG_RECORD_DIRECTORY;
menu[i++].function = recdirectory; menu[i++].function = recdirectory;
m=menu_init( menu, i, NULL ); m=menu_init( menu, i, NULL );

34
firmware/export/talk.h Normal file
View 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__ */

View file

@ -2134,6 +2134,7 @@ void mpeg_record(char *filename)
recording_filename[MAX_PATH - 1] = 0; recording_filename[MAX_PATH - 1] = 0;
disable_xing_header = false; disable_xing_header = false;
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
queue_post(&mpeg_queue, MPEG_RECORD, NULL); queue_post(&mpeg_queue, MPEG_RECORD, NULL);
} }
@ -2148,6 +2149,7 @@ static void start_prerecording(void)
prerecord_timeout = current_tick + HZ; prerecord_timeout = current_tick + HZ;
memset(prerecord_buffer, 0, sizeof(prerecord_buffer)); memset(prerecord_buffer, 0, sizeof(prerecord_buffer));
reset_mp3_buffer(); reset_mp3_buffer();
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
is_prerecording = true; is_prerecording = true;
@ -2404,6 +2406,7 @@ void mpeg_play(int offset)
#else #else
is_playing = true; is_playing = true;
talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
queue_post(&mpeg_queue, MPEG_PLAY, (void*)offset); queue_post(&mpeg_queue, MPEG_PLAY, (void*)offset);
#endif /* #ifdef SIMULATOR */ #endif /* #ifdef SIMULATOR */

209
firmware/talk.c Normal file
View 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;
}

View file

@ -225,3 +225,22 @@ void button_set_flip(bool yesno)
{ {
(void)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;
}