diff options
author | William Wilgus <wilgus.william@gmail.com> | 2020-09-20 13:29:02 -0400 |
---|---|---|
committer | William Wilgus <wilgus.william@gmail.com> | 2020-09-20 16:08:49 -0400 |
commit | 2ffe87902dc72b4c26032c94e8250ff92d2888dc (patch) | |
tree | 9a6cf73d37a5a5e3f93813b44720c1bd5604ddd9 /apps/talk.c | |
parent | c528c01312d85e2d177bcc05ce82a29c97b803cc (diff) | |
download | rockbox-2ffe87902d.tar.gz rockbox-2ffe87902d.zip |
Add Invalid Voice Announcement to the voice system FS#13216
When a voice file is invalid or fails to load the voice system splash a
message 'Invalid Voice'
Now we supply a single voice file (currently only english is used)
the support for other languages is in but I haven't set it up to
look for anything but InvalidVoice_english.talk
Also adds a one time kill voice thread function
ie. it doesn't allow re-init after killing the voice thread & queue
Change-Id: I7b43f340c3cc65c65110190f0e0075b31218a7ac
Diffstat (limited to 'apps/talk.c')
-rw-r--r-- | apps/talk.c | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/apps/talk.c b/apps/talk.c index 5d292b05d1..29f1331983 100644 --- a/apps/talk.c +++ b/apps/talk.c @@ -535,7 +535,6 @@ static bool load_header(int fd, struct voicefile_header *hdr) static bool create_clip_buffer(size_t max_size) { - size_t alloc_size; /* just allocate, populate on an as-needed basis later */ talk_handle = core_alloc_ex("voice data", max_size, &talk_ops); if (talk_handle < 0) @@ -543,16 +542,12 @@ static bool create_clip_buffer(size_t max_size) buflib_init(&clip_ctx, core_get_data(talk_handle), max_size); - /* the first alloc is the clip metadata table */ - alloc_size = max_clips * sizeof(struct clip_cache_metadata); - metadata_table_handle = buflib_alloc(&clip_ctx, alloc_size); - memset(buflib_get_data(&clip_ctx, metadata_table_handle), 0, alloc_size); - return true; alloc_err: talk_status = TALK_STATUS_ERR_ALLOC; - index_handle = core_free(index_handle); + if (index_handle > 0) + index_handle = core_free(index_handle); return false; } @@ -608,6 +603,7 @@ static bool load_voicefile_data(int fd) * other allocs succeed without disabling voice which would require * reloading the voice from disk (as we do not shrink our buffer when * other code attempts new allocs these would fail) */ + size_t metadata_alloc_size; ssize_t cap = MIN(MAX_CLIP_BUFFER_SIZE, audio_buffer_available() - (64<<10)); if (UNLIKELY(cap < 0)) { @@ -625,6 +621,11 @@ static bool load_voicefile_data(int fd) if (!create_clip_buffer(voicebuf_size)) return false; + /* the first alloc is the clip metadata table */ + metadata_alloc_size = max_clips * sizeof(struct clip_cache_metadata); + metadata_table_handle = buflib_alloc(&clip_ctx, metadata_alloc_size); + memset(buflib_get_data(&clip_ctx, metadata_table_handle), 0, metadata_alloc_size); + load_initial_clips(fd); /* make sure to have the silence clip, if available return value can * be cached globally even for TALK_PROGRESSIVE_LOAD because the @@ -1499,6 +1500,56 @@ void talk_time(const struct tm *tm, bool enqueue) } } +void talk_announce_voice_invalid(void) +{ + int voice_fd; + int voice_sz; + int buf_handle; + struct queue_entry qe; + + const char talkfile[] = + LANG_DIR "/InvalidVoice_" DEFAULT_VOICE_LANG ".talk"; + + if (global_settings.talk_menu && talk_status != TALK_STATUS_OK && !button_hold()) + { + talk_temp_disable_count = 0xFF; /* don't let anyone else use voice sys */ + + voice_fd = open(talkfile, O_RDONLY); + if (voice_fd < 0) + return; /* can't open */ + + voice_sz= lseek(voice_fd, 0, SEEK_END); + if (voice_sz == 0 || voice_sz > (64<<10)) + return; /* nothing here or too big */ + + lseek(voice_fd, 0, SEEK_SET); + /* add a bit extra for buflib overhead (2K) */ + if (!create_clip_buffer(ALIGN_UP(voice_sz, sizeof(long)) + (2<<10))) + return; + mutex_lock(&read_buffer_mutex); + buf_handle = buflib_alloc(&clip_ctx, ALIGN_UP(voice_sz, sizeof(long))); + + if (buf_handle < 0) + return; + + if (read_to_handle_ex(voice_fd, &clip_ctx, buf_handle, 0, voice_sz) > 0) + { + voice_thread_init(); + qe.handle = buf_handle; + qe.length = qe.remaining = voice_sz; + queue_clip(&qe, false); + voice_wait(); + voice_thread_kill(); + } + + mutex_unlock(&read_buffer_mutex); + close(voice_fd); + + buf_handle = buflib_free(&clip_ctx, buf_handle); + talk_handle = core_free(talk_handle); + } +} + bool talk_get_debug_data(struct talk_debug_data *data) { char* p_lang = DEFAULT_VOICE_LANG; /* default */ |