Jörg Hohensohn | fa97f16 | 2004-03-19 22:15:53 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * __________ __ ___. |
| 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | * \/ \/ \/ \/ \/ |
| 8 | * $Id$ |
| 9 | * |
Nicolas Pennequin | 357ffb3 | 2008-05-05 10:32:46 +0000 | [diff] [blame] | 10 | * Copyright (C) 2004 Jörg Hohensohn |
Jörg Hohensohn | fa97f16 | 2004-03-19 22:15:53 +0000 | [diff] [blame] | 11 | * |
| 12 | * This module collects the Talkbox and voice UI functions. |
| 13 | * (Talkbox reads directory names from mp3 clips called thumbnails, |
| 14 | * the voice UI lets menus and screens "talk" from a voicefont in memory. |
| 15 | * |
Daniel Stenberg | 2acc0ac | 2008-06-28 18:10:04 +0000 | [diff] [blame^] | 16 | * This program is free software; you can redistribute it and/or |
| 17 | * modify it under the terms of the GNU General Public License |
| 18 | * as published by the Free Software Foundation; either version 2 |
| 19 | * of the License, or (at your option) any later version. |
Jörg Hohensohn | fa97f16 | 2004-03-19 22:15:53 +0000 | [diff] [blame] | 20 | * |
| 21 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| 22 | * KIND, either express or implied. |
| 23 | * |
| 24 | ****************************************************************************/ |
| 25 | |
| 26 | #ifndef __TALK_H__ |
| 27 | #define __TALK_H__ |
| 28 | |
| 29 | #include <stdbool.h> |
Nils Wallménius | acbd780 | 2007-11-20 19:50:52 +0000 | [diff] [blame] | 30 | #include <inttypes.h> |
Jonathan Gordon | d7d6b78 | 2007-10-07 08:12:01 +0000 | [diff] [blame] | 31 | #include "time.h" |
Jörg Hohensohn | fa97f16 | 2004-03-19 22:15:53 +0000 | [diff] [blame] | 32 | |
Michael Sevakis | 99617d7 | 2007-11-18 17:12:19 +0000 | [diff] [blame] | 33 | #define VOICE_VERSION 400 /* 4.00 - if you change this, change it in voicefont too */ |
Nils Wallménius | f801714 | 2007-11-15 19:32:15 +0000 | [diff] [blame] | 34 | |
Jörg Hohensohn | fa97f16 | 2004-03-19 22:15:53 +0000 | [diff] [blame] | 35 | enum { |
Michael Sevakis | 287deb0 | 2006-09-26 17:44:43 +0000 | [diff] [blame] | 36 | /* See array "unit_voiced" in talk.c function "talk_value" */ |
Jörg Hohensohn | fa97f16 | 2004-03-19 22:15:53 +0000 | [diff] [blame] | 37 | UNIT_INT = 1, /* plain number */ |
| 38 | UNIT_SIGNED, /* number with mandatory sign (even if positive) */ |
| 39 | UNIT_MS, /* milliseconds */ |
| 40 | UNIT_SEC, /* seconds */ |
| 41 | UNIT_MIN, /* minutes */ |
| 42 | UNIT_HOUR, /* hours */ |
| 43 | UNIT_KHZ, /* kHz */ |
| 44 | UNIT_DB, /* dB, mandatory sign */ |
| 45 | UNIT_PERCENT, /* % */ |
Jörg Hohensohn | beec2e9 | 2004-03-20 16:49:58 +0000 | [diff] [blame] | 46 | UNIT_MAH, /* milliAmp hours */ |
| 47 | UNIT_PIXEL, /* pixels */ |
| 48 | UNIT_PER_SEC, /* per second */ |
| 49 | UNIT_HERTZ, /* hertz */ |
Martin Scarratt | 9130a2a | 2006-07-22 17:23:05 +0000 | [diff] [blame] | 50 | UNIT_MB, /* Megabytes */ |
Michael Sevakis | 4fc717a | 2006-08-28 22:38:41 +0000 | [diff] [blame] | 51 | UNIT_KBIT, /* kilobits per sec */ |
Peter D'Hoye | ebcf06d | 2007-08-18 23:03:03 +0000 | [diff] [blame] | 52 | UNIT_PM_TICK, /* peak meter units per tick */ |
Stéphane Doyon | 8b8785b | 2007-11-03 03:43:12 +0000 | [diff] [blame] | 53 | UNIT_TIME_EXACT,/* time duration/interval in seconds, says hours,mins,secs*/ |
| 54 | UNIT_TIME, /* as above but less verbose */ |
Jörg Hohensohn | fa97f16 | 2004-03-19 22:15:53 +0000 | [diff] [blame] | 55 | UNIT_LAST /* END MARKER */ |
| 56 | }; |
| 57 | |
Michael Sevakis | 287deb0 | 2006-09-26 17:44:43 +0000 | [diff] [blame] | 58 | #define UNIT_SHIFT (32-5) /* this many bits left from UNIT_xx enum */ |
Jörg Hohensohn | fa97f16 | 2004-03-19 22:15:53 +0000 | [diff] [blame] | 59 | |
Nils Wallménius | 05d2bfd | 2008-04-19 13:19:04 +0000 | [diff] [blame] | 60 | #define DECIMAL_SHIFT (32 - 8) |
| 61 | |
Jörg Hohensohn | fa97f16 | 2004-03-19 22:15:53 +0000 | [diff] [blame] | 62 | /* make a "talkable" ID from number + unit |
| 63 | unit is upper 4 bits, number the remaining (in regular 2's complement) */ |
Jean-Philippe Bernardy | 45e0de3 | 2005-02-12 11:26:36 +0000 | [diff] [blame] | 64 | #define TALK_ID(n,u) (((long)(u))<<UNIT_SHIFT | ((n) & ~(-1L<<UNIT_SHIFT))) |
Jörg Hohensohn | fa97f16 | 2004-03-19 22:15:53 +0000 | [diff] [blame] | 65 | |
Nils Wallménius | 05d2bfd | 2008-04-19 13:19:04 +0000 | [diff] [blame] | 66 | /* make a "talkable" ID from a decimal number + unit, the decimal number |
Nils Wallménius | 2521bf5 | 2008-04-20 11:02:42 +0000 | [diff] [blame] | 67 | is represented like x*10^d where d is the number of decimal digits */ |
Nils Wallménius | 05d2bfd | 2008-04-19 13:19:04 +0000 | [diff] [blame] | 68 | #define TALK_ID_DECIMAL(n,d,u) (((long)(u))<<UNIT_SHIFT |\ |
| 69 | ((long)(d))<<DECIMAL_SHIFT |\ |
| 70 | ((n) & ~(-1L<<DECIMAL_SHIFT))) |
| 71 | |
Jörg Hohensohn | b1403ee | 2004-07-23 23:01:20 +0000 | [diff] [blame] | 72 | /* convenience macro to have both virtual pointer and ID as arguments */ |
| 73 | #define STR(id) ID2P(id), id |
Jörg Hohensohn | fa97f16 | 2004-03-19 22:15:53 +0000 | [diff] [blame] | 74 | |
Jörg Hohensohn | 40ae63b | 2004-10-21 18:34:48 +0000 | [diff] [blame] | 75 | /* publish these strings, so they're stored only once (better than #define) */ |
Jörg Hohensohn | d484420 | 2004-10-06 21:37:46 +0000 | [diff] [blame] | 76 | extern const char* const dir_thumbnail_name; /* "_dirname.talk" */ |
Jörg Hohensohn | 40ae63b | 2004-10-21 18:34:48 +0000 | [diff] [blame] | 77 | extern const char* const file_thumbnail_ext; /* ".talk" for file voicing */ |
Jörg Hohensohn | fa97f16 | 2004-03-19 22:15:53 +0000 | [diff] [blame] | 78 | |
| 79 | void talk_init(void); |
Jens Arnold | 2597a13 | 2006-12-25 14:01:47 +0000 | [diff] [blame] | 80 | #if CONFIG_CODEC == SWCODEC |
Linus Nielsen Feltzing | 42f0ad3 | 2006-08-15 18:01:42 +0000 | [diff] [blame] | 81 | bool talk_voice_required(void); /* returns true if voice codec required */ |
Jens Arnold | 2597a13 | 2006-12-25 14:01:47 +0000 | [diff] [blame] | 82 | #endif |
Miika Pekkarinen | 159c52d | 2005-08-20 11:13:19 +0000 | [diff] [blame] | 83 | int talk_get_bufsize(void); /* get the loaded voice file size */ |
Steve Bavin | 32a9575 | 2007-10-19 15:31:42 +0000 | [diff] [blame] | 84 | void talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */ |
Nils Wallménius | 5b76936 | 2007-08-06 13:08:36 +0000 | [diff] [blame] | 85 | bool is_voice_queued(void); /* Are there more voice clips to be spoken? */ |
Nils Wallménius | acbd780 | 2007-11-20 19:50:52 +0000 | [diff] [blame] | 86 | int talk_id(int32_t id, bool enqueue); /* play a voice ID from voicefont */ |
Jens Arnold | 8fb3361 | 2004-08-18 01:09:31 +0000 | [diff] [blame] | 87 | int talk_file(const char* filename, bool enqueue); /* play a thumbnail from file */ |
Jean-Philippe Bernardy | 45e0de3 | 2005-02-12 11:26:36 +0000 | [diff] [blame] | 88 | int talk_number(long n, bool enqueue); /* say a number */ |
| 89 | int talk_value(long n, int unit, bool enqueue); /* say a numeric value */ |
Nils Wallménius | 05d2bfd | 2008-04-19 13:19:04 +0000 | [diff] [blame] | 90 | int talk_value_decimal(long n, int unit, int decimals, bool enqueue); |
Jens Arnold | 8fb3361 | 2004-08-18 01:09:31 +0000 | [diff] [blame] | 91 | int talk_spell(const char* spell, bool enqueue); /* spell a string */ |
Steve Bavin | cd88e2a | 2008-03-25 15:24:03 +0000 | [diff] [blame] | 92 | void talk_setting(const void *global_settings_variable); /* read a setting */ |
Steve Bavin | 32a9575 | 2007-10-19 15:31:42 +0000 | [diff] [blame] | 93 | void talk_disable(bool disable); /* temporarily disable (or re-enable) talking (temporarily, not persisted) */ |
| 94 | void talk_force_shutup(void); /* kill voice unconditionally */ |
| 95 | void talk_shutup(void); /* Interrupt voice, as when enqueue is false */ |
Nils Wallménius | 1ff0c35 | 2007-08-06 15:01:45 +0000 | [diff] [blame] | 96 | |
Nils Wallménius | 2521bf5 | 2008-04-20 11:02:42 +0000 | [diff] [blame] | 97 | /* helper function for speaking fractional numbers */ |
| 98 | void talk_fractional(char *tbuf, int value, int unit); |
| 99 | |
Jonathan Gordon | d7d6b78 | 2007-10-07 08:12:01 +0000 | [diff] [blame] | 100 | #if CONFIG_RTC |
Steve Bavin | 072a3c5 | 2007-10-24 12:32:12 +0000 | [diff] [blame] | 101 | void talk_time(struct tm *tm, bool enqueue); |
| 102 | void talk_date(struct tm *tm, bool enqueue); |
Jonathan Gordon | d7d6b78 | 2007-10-07 08:12:01 +0000 | [diff] [blame] | 103 | #endif /* CONFIG_RTC */ |
| 104 | |
Nils Wallménius | 1ff0c35 | 2007-08-06 15:01:45 +0000 | [diff] [blame] | 105 | /* This (otherwise invalid) ID signals the end of the array. */ |
| 106 | #define TALK_FINAL_ID LANG_LAST_INDEX_IN_ARRAY |
| 107 | |
Nils Wallménius | 5b76936 | 2007-08-06 13:08:36 +0000 | [diff] [blame] | 108 | /* Enqueue next utterance even if enqueue parameter is false: don't |
| 109 | interrupt the current utterance. */ |
| 110 | void talk_force_enqueue_next(void); |
| 111 | |
| 112 | /* speaks one or more IDs (from an array)). */ |
| 113 | int talk_idarray(long *idarray, bool enqueue); |
Nils Wallménius | 5b76936 | 2007-08-06 13:08:36 +0000 | [diff] [blame] | 114 | /* This makes an initializer for the array of IDs and takes care to |
| 115 | put the final sentinel element at the end. */ |
| 116 | #define TALK_IDARRAY(ids...) ((long[]){ids,TALK_FINAL_ID}) |
| 117 | /* And this handy macro makes it look like a variadic function. */ |
| 118 | #define talk_ids(enqueue, ids...) talk_idarray(TALK_IDARRAY(ids), enqueue) |
| 119 | /* This version talks only if talking menus are enabled, and does not |
| 120 | enqueue the initial id. */ |
| 121 | #define cond_talk_ids(ids...) do { \ |
Steve Bavin | 32a9575 | 2007-10-19 15:31:42 +0000 | [diff] [blame] | 122 | if (global_settings.talk_menu) \ |
Nils Wallménius | 5b76936 | 2007-08-06 13:08:36 +0000 | [diff] [blame] | 123 | talk_ids(false, ids); \ |
| 124 | } while(0) |
| 125 | /* And a version that takes the array parameter... */ |
| 126 | #define cond_talk_idarray(idarray) do { \ |
Steve Bavin | 32a9575 | 2007-10-19 15:31:42 +0000 | [diff] [blame] | 127 | if (global_settings.talk_menu \ |
Nils Wallménius | 5b76936 | 2007-08-06 13:08:36 +0000 | [diff] [blame] | 128 | talk_idarray(idarray, false); \ |
| 129 | } while(0) |
| 130 | /* Convenience macro to conditionally speak something and not have |
| 131 | it interrupted. */ |
| 132 | #define cond_talk_ids_fq(ids...) do { \ |
Steve Bavin | 32a9575 | 2007-10-19 15:31:42 +0000 | [diff] [blame] | 133 | if (global_settings.talk_menu) { \ |
Nils Wallménius | 5b76936 | 2007-08-06 13:08:36 +0000 | [diff] [blame] | 134 | talk_ids(false, ids); \ |
| 135 | talk_force_enqueue_next(); \ |
| 136 | } \ |
| 137 | }while(0) |
Jonathan Gordon | c14430a | 2007-11-07 09:28:07 +0000 | [diff] [blame] | 138 | |
Jörg Hohensohn | fa97f16 | 2004-03-19 22:15:53 +0000 | [diff] [blame] | 139 | #endif /* __TALK_H__ */ |