summaryrefslogtreecommitdiff
path: root/apps/talk.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/talk.c')
-rw-r--r--apps/talk.c372
1 files changed, 189 insertions, 183 deletions
diff --git a/apps/talk.c b/apps/talk.c
index 4c4e6184b8..820cb75c8d 100644
--- a/apps/talk.c
+++ b/apps/talk.c
@@ -46,6 +46,7 @@
46#include "structec.h" 46#include "structec.h"
47#include "plugin.h" /* plugin_get_buffer() */ 47#include "plugin.h" /* plugin_get_buffer() */
48#include "debug.h" 48#include "debug.h"
49#include "panic.h"
49 50
50/* Memory layout varies between targets because the 51/* Memory layout varies between targets because the
51 Archos (MASCODEC) devices cannot mix voice and audio playback 52 Archos (MASCODEC) devices cannot mix voice and audio playback
@@ -115,8 +116,15 @@ struct voicefile_header /* file format of our voice file */
115 * together with codecs, so we load clips each time they are accessed. 116 * together with codecs, so we load clips each time they are accessed.
116 * The Ondios have slow storage access and loading the entire voice file would 117 * The Ondios have slow storage access and loading the entire voice file would
117 * take several seconds, so we use the same mechanism. */ 118 * take several seconds, so we use the same mechanism. */
118#define TALK_PARTIAL_LOAD 119#define TALK_PROGRESSIVE_LOAD
119#define MAX_CLIP_BUFFER_SIZE 100000 /* 70+ clips should fit into 100k */ 120#if !defined(ONDIO_SERIES)
121/* 70+ clips should fit into 100k */
122#define MAX_CLIP_BUFFER_SIZE (100000)
123#endif
124#endif
125
126#ifndef MAX_CLIP_BUFFER_SIZE
127#define MAX_CLIP_BUFFER_SIZE (1<<30) /* 1GB should be enough for everybody */
120#endif 128#endif
121 129
122/* Multiple thumbnails can be loaded back-to-back in this buffer. */ 130/* Multiple thumbnails can be loaded back-to-back in this buffer. */
@@ -144,10 +152,9 @@ static unsigned char last_lang[MAX_FILENAME+1]; /* name of last used lang file (
144static bool talk_initialized; /* true if talk_init has been called */ 152static bool talk_initialized; /* true if talk_init has been called */
145static bool give_buffer_away; /* true if we should give the buffers away in shrink_callback if requested */ 153static bool give_buffer_away; /* true if we should give the buffers away in shrink_callback if requested */
146static int talk_temp_disable_count; /* if positive, temporarily disable voice UI (not saved) */ 154static int talk_temp_disable_count; /* if positive, temporarily disable voice UI (not saved) */
147 /* size of the loaded voice file 155 /* size of the voice data in the voice file and the actually allocated buffer
148 * offsets smaller than this denote a clip from teh voice file, 156 * for it. voicebuf_size is always smaller or equal to voicefile_size */
149 * offsets larger than this denote a thumbnail clip */ 157static unsigned long voicefile_size, voicebuf_size;
150static unsigned long voicefile_size;
151 158
152struct queue_entry /* one entry of the internal queue */ 159struct queue_entry /* one entry of the internal queue */
153{ 160{
@@ -158,15 +165,11 @@ struct queue_entry /* one entry of the internal queue */
158 * into the bits of the above members (as a space saver). For small values 165 * into the bits of the above members (as a space saver). For small values
159 * the required extra code outweights this so it's not done here */ 166 * the required extra code outweights this so it's not done here */
160 enum offset_type { 167 enum offset_type {
161 TALK_OFFSET,
162 THUMB_OFFSET,
163#ifdef TALK_PARTIAL_LOAD
164 TALK_HANDLE, 168 TALK_HANDLE,
165#endif 169 THUMB_OFFSET,
166 } type; 170 } type;
167}; 171};
168 172
169#ifdef TALK_PARTIAL_LOAD
170static struct buflib_context clip_ctx; 173static struct buflib_context clip_ctx;
171 174
172struct clip_cache_metadata { 175struct clip_cache_metadata {
@@ -177,7 +180,6 @@ struct clip_cache_metadata {
177static int metadata_table_handle; 180static int metadata_table_handle;
178static unsigned max_clips; 181static unsigned max_clips;
179static int cache_hits, cache_misses; 182static int cache_hits, cache_misses;
180#endif
181 183
182static struct queue_entry queue[QUEUE_SIZE]; /* queue of scheduled clips */ 184static struct queue_entry queue[QUEUE_SIZE]; /* queue of scheduled clips */
183static struct queue_entry silence, *last_clip; 185static struct queue_entry silence, *last_clip;
@@ -189,11 +191,8 @@ static int index_handle, talk_handle, thumb_handle;
189static int move_callback(int handle, void *current, void *new) 191static int move_callback(int handle, void *current, void *new)
190{ 192{
191 (void)handle; (void)current; (void)new; 193 (void)handle; (void)current; (void)new;
192#ifdef TALK_PARTIAL_LOAD 194 if (handle == talk_handle && !buflib_context_relocate(&clip_ctx, new))
193 if (handle == talk_handle) 195 return BUFLIB_CB_CANNOT_MOVE;
194 if (!buflib_context_relocate(&clip_ctx, new))
195 return BUFLIB_CB_CANNOT_MOVE;
196#endif
197 return BUFLIB_CB_OK; 196 return BUFLIB_CB_OK;
198} 197}
199 198
@@ -349,7 +348,24 @@ static int id2index(int id)
349 return index; 348 return index;
350} 349}
351 350
352#ifdef TALK_PARTIAL_LOAD 351static int index2id(int index)
352{
353 int id = index;
354
355 if (index >= voicefile.id2_max + voicefile.id1_max)
356 return -1;
357
358 if (index >= voicefile.id1_max)
359 { /* must be voice-only if it exceeds table 1 */
360 id -= voicefile.id1_max;
361 /* The first string comes after VOICEONLY_DELIMITER so we need to
362 add VOICEONLY_DELIMITER + 1 */
363 id += VOICEONLY_DELIMITER + 1;
364 }
365
366 return id;
367}
368
353static int free_oldest_clip(void) 369static int free_oldest_clip(void)
354{ 370{
355 unsigned i; 371 unsigned i;
@@ -374,7 +390,89 @@ static int free_oldest_clip(void)
374 390
375 return oldest; 391 return oldest;
376} 392}
393
394
395/* common code for load_initial_clips() and get_clip() */
396static void add_cache_entry(int clip_handle, int table_index, int id)
397{
398 unsigned i;
399 struct clip_cache_metadata *cc = buflib_get_data(&clip_ctx, metadata_table_handle);
400
401 if (table_index != -1)
402 {
403 /* explicit slot; use that */
404 cc = &cc[table_index];
405 if (cc->handle > 0) panicf("%s(): Slot already used", __func__);
406 }
407 else
408 { /* find an empty slot */
409 for(i = 0; cc[i].handle && i < max_clips; i++) ;
410 if (i == max_clips) /* no free slot in the cache table? */
411 i = free_oldest_clip();
412 cc = &cc[i];
413 }
414 cc->handle = clip_handle;
415 cc->tick = current_tick;
416 cc->voice_id = id;
417}
418
419static ssize_t read_clip_data(int fd, int index, int clip_handle)
420{
421 struct clip_entry* clipbuf;
422 size_t clipsize;
423 ssize_t ret;
424
425 if (fd < 0)
426 {
427 buflib_free(&clip_ctx, clip_handle);
428 return -1; /* open error */
429 }
430
431 clipbuf = core_get_data(index_handle);
432 /* this must not be called with LOADED_MASK set in clipsize */
433 clipsize = clipbuf[index].size;
434 lseek(fd, clipbuf[index].offset, SEEK_SET);
435 ret = read_to_handle_ex(fd, &clip_ctx, clip_handle, 0, clipsize);
436
437 if (ret < 0 || clipsize != (size_t)ret)
438 {
439 buflib_free(&clip_ctx, clip_handle);
440 return -2; /* read error */
441 }
442
443 clipbuf = core_get_data(index_handle);
444 clipbuf[index].size |= LOADED_MASK; /* mark as loaded */
445
446 return ret;
447}
448
449static void load_initial_clips(int fd)
450{
451 (void) fd;
452#ifndef TALK_PROGRESSIVE_LOAD
453 unsigned index, i;
454 unsigned num_clips = voicefile.id1_max + voicefile.id2_max;
455
456 for(index = i = 0; index < num_clips && i < max_clips; index++)
457 {
458 int handle;
459 struct clip_entry* clipbuf = core_get_data(index_handle);
460 size_t clipsize = clipbuf[index].size;
461 if (clipsize == 0) /* clip not included in voicefile */
462 continue;
463
464 handle = buflib_alloc(&clip_ctx, clipsize);
465 if (handle < 0)
466 break;
467
468 if (read_clip_data(fd, index, handle) < 0)
469 break;
470
471 add_cache_entry(handle, i++, index2id(index));
472 }
377#endif 473#endif
474}
475
378/* fetch a clip from the voice file */ 476/* fetch a clip from the voice file */
379static int get_clip(long id, struct queue_entry *q) 477static int get_clip(long id, struct queue_entry *q)
380{ 478{
@@ -393,16 +491,9 @@ static int get_clip(long id, struct queue_entry *q)
393 if (clipsize == 0) /* clip not included in voicefile */ 491 if (clipsize == 0) /* clip not included in voicefile */
394 return -1; 492 return -1;
395 493
396#ifndef TALK_PARTIAL_LOAD
397 retval = clipbuf[index].offset;
398 type = TALK_OFFSET;
399
400#else
401 if (!(clipsize & LOADED_MASK)) 494 if (!(clipsize & LOADED_MASK))
402 { /* clip needs loading */ 495 { /* clip needs loading */
403 struct clip_cache_metadata *cc;
404 int fd, handle, oldest = -1; 496 int fd, handle, oldest = -1;
405 unsigned i;
406 ssize_t ret; 497 ssize_t ret;
407 cache_misses++; 498 cache_misses++;
408 /* free clips from cache until this one succeeds to allocate */ 499 /* free clips from cache until this one succeeds to allocate */
@@ -411,40 +502,12 @@ static int get_clip(long id, struct queue_entry *q)
411 /* handle should now hold a valid alloc. Load from disk 502 /* handle should now hold a valid alloc. Load from disk
412 * and insert into cache */ 503 * and insert into cache */
413 fd = open_voicefile(); 504 fd = open_voicefile();
414 if (fd < 0) 505 ret = read_clip_data(fd, index, handle);
415 {
416 buflib_free(&clip_ctx, handle);
417 return -1; /* open error */
418 }
419 clipbuf = core_get_data(index_handle);
420 lseek(fd, clipbuf[index].offset, SEEK_SET);
421 ret = read_to_handle_ex(fd, &clip_ctx, handle, 0, clipsize);
422 close(fd); 506 close(fd);
423 507 if (ret < 0)
424 if (ret < 0 || clipsize != (size_t)ret) 508 return ret;
425 {
426 buflib_free(&clip_ctx, handle);
427 return -1; /* read error */
428 }
429
430 clipbuf = core_get_data(index_handle);
431 clipbuf[index].size |= LOADED_MASK; /* mark as loaded */
432
433 /* finally insert into metadata table */ 509 /* finally insert into metadata table */
434 cc = buflib_get_data(&clip_ctx, metadata_table_handle); 510 add_cache_entry(handle, oldest, id);
435 if (oldest != -1)
436 /* went through the cache in the above loop already, re-use the slot */
437 cc = &cc[oldest];
438 else
439 { /* find an empty slot */
440 for(i = 0; cc[i].handle && i < max_clips; i++) ;
441 if (i == max_clips) /* no free slot in the cache table? */
442 i = free_oldest_clip();
443 cc = &cc[i];
444 }
445 cc->handle = handle;
446 cc->tick = current_tick;
447 cc->voice_id = id;
448 retval = handle; 511 retval = handle;
449 } 512 }
450 else 513 else
@@ -459,7 +522,6 @@ static int get_clip(long id, struct queue_entry *q)
459 retval = cc[i].handle; 522 retval = cc[i].handle;
460 } 523 }
461 type = TALK_HANDLE; 524 type = TALK_HANDLE;
462#endif /* TALK_PARTIAL_LOAD */
463 525
464 q->offset = retval; 526 q->offset = retval;
465 q->length = clipsize; 527 q->length = clipsize;
@@ -483,15 +545,6 @@ static bool load_index_table(int fd, const struct voicefile_header *hdr)
483 545
484 ret = read_to_handle(fd, index_handle, 0, alloc_size); 546 ret = read_to_handle(fd, index_handle, 0, alloc_size);
485 547
486#ifndef TALK_PARTIAL_LOAD
487 int clips_offset, num_clips;
488 /* adjust the offsets of the clips, they are relative to the file
489 * TALK_PARTUAL_LOAD needs the file offset instead as it loads
490 * the clips later */
491 clips_offset = hdr->table;
492 num_clips = hdr->id1_max + hdr->id2_max;
493 clips_offset += num_clips * sizeof(struct clip_entry); /* skip index */
494#endif
495 if (ret == alloc_size) 548 if (ret == alloc_size)
496 { 549 {
497 buf = core_get_data(index_handle); 550 buf = core_get_data(index_handle);
@@ -501,9 +554,6 @@ static bool load_index_table(int fd, const struct voicefile_header *hdr)
501 /* doesn't yield() */ 554 /* doesn't yield() */
502 structec_convert(&buf[i], "ll", 1, true); 555 structec_convert(&buf[i], "ll", 1, true);
503#endif 556#endif
504#ifndef TALK_PARTIAL_LOAD
505 buf[i].offset -= clips_offset;
506#endif
507 } 557 }
508 } 558 }
509 else 559 else
@@ -525,27 +575,28 @@ static bool load_header(int fd, struct voicefile_header *hdr)
525 return true; 575 return true;
526} 576}
527 577
528#ifndef TALK_PARTIAL_LOAD 578static bool create_clip_buffer(size_t max_size)
529static bool load_data(int fd, ssize_t size_to_read)
530{ 579{
531 ssize_t ret; 580 size_t alloc_size;
532 581 /* just allocate, populate on an as-needed basis later */
533 if (size_to_read < 0) 582 talk_handle = core_alloc_ex("voice data", max_size, &talk_ops);
534 return false;
535
536 talk_handle = core_alloc_ex("voice data", size_to_read, &talk_ops);
537 if (talk_handle < 0) 583 if (talk_handle < 0)
538 return false; 584 goto alloc_err;
539 585
540 ret = read_to_handle(fd, talk_handle, 0, size_to_read); 586 buflib_init(&clip_ctx, core_get_data(talk_handle), max_size);
541 587
542 if (ret != size_to_read) 588 /* the first alloc is the clip metadata table */
543 talk_handle = core_free(talk_handle); 589 alloc_size = max_clips * sizeof(struct clip_cache_metadata);
590 metadata_table_handle = buflib_alloc(&clip_ctx, alloc_size);
591 memset(buflib_get_data(&clip_ctx, metadata_table_handle), 0, alloc_size);
544 592
545 return ret == size_to_read; 593 return true;
546}
547#endif
548 594
595alloc_err:
596 index_handle = core_free(index_handle);
597 return false;
598}
599
549static bool alloc_thumbnail_buf(void) 600static bool alloc_thumbnail_buf(void)
550{ 601{
551 int handle; 602 int handle;
@@ -565,7 +616,8 @@ static bool alloc_thumbnail_buf(void)
565#else 616#else
566 /* on HWCODEC, just use the rest of the remaining buffer, 617 /* on HWCODEC, just use the rest of the remaining buffer,
567 * normal playback cannot happen anyway */ 618 * normal playback cannot happen anyway */
568 handle = core_alloc_maximum("voice thumb", &size, &thumb_ops); 619 size = audio_buffer_available();
620 handle = core_alloc_ex("voice thumb", size, &thumb_ops);
569#endif 621#endif
570 thumb_handle = handle; 622 thumb_handle = handle;
571 size_for_thumbnail = (handle > 0) ? size : 0; 623 size_for_thumbnail = (handle > 0) ? size : 0;
@@ -597,47 +649,46 @@ static bool load_voicefile_index(int fd)
597 return false; 649 return false;
598} 650}
599 651
600static bool load_voicefile_data(int fd, size_t max_size) 652/* this function caps the voicefile buffer and allocates it. It can
653 * be called after talk_init(), e.g. when the voice was temporarily disabled.
654 * The buffer size has to be capped again each time because the available
655 * audio buffer changes over time */
656static bool load_voicefile_data(int fd)
601{ 657{
602#ifdef TALK_PARTIAL_LOAD 658 voicebuf_size = voicefile_size;
603 (void)fd; 659 /* cap to the max. number of clips or the size of the available audio
604 size_t alloc_size; 660 * buffer which we grab. We leave some to the rest of the system.
661 * While that reduces our buffer size it improves the chance that
662 * other allocs succeed without disabling voice which would require
663 * reloading the voice from disk (as we do not shrink our buffer when
664 * other code attempts new allocs these would fail) */
665 ssize_t cap = MIN(MAX_CLIP_BUFFER_SIZE, audio_buffer_available() - (64<<10));
666 if (UNLIKELY(cap < 0))
667 {
668 logf("Not enough memory for voice. Disabling...\n");
669 return false;
670 }
671 else if (voicebuf_size > (size_t)cap)
672 voicebuf_size = cap;
673
605 /* just allocate, populate on an as-needed basis later 674 /* just allocate, populate on an as-needed basis later
606 * re-create the clip buffer to ensure clip_ctx is up-to-date */ 675 * re-create the clip buffer to ensure clip_ctx is up-to-date */
607 if (talk_handle > 0) 676 if (talk_handle > 0)
608 talk_handle = core_free(talk_handle); 677 talk_handle = core_free(talk_handle);
609 talk_handle = core_alloc_ex("voice data", max_size, &talk_ops); 678 if (!create_clip_buffer(voicebuf_size))
610 if (talk_handle < 0) 679 return false;
611 goto load_err_free;
612
613 buflib_init(&clip_ctx, core_get_data(talk_handle), max_size);
614
615 alloc_size = max_clips * sizeof(struct clip_cache_metadata);
616 /* the first alloc is the clip metadata table */
617 metadata_table_handle = buflib_alloc(&clip_ctx, alloc_size);
618 memset(buflib_get_data(&clip_ctx, metadata_table_handle), 0, alloc_size);
619
620#else
621 /* load the entire file into memory */
622 if (!load_data(fd, max_size))
623 goto load_err_free;
624#endif
625 680
626 /* make sure to have the silence clip, if available 681 load_initial_clips(fd);
627 * return value can be cached globally even for TALK_PARTIAL_LOAD because 682 /* make sure to have the silence clip, if available return value can
628 * the VOICE_PAUSE clip is specially handled */ 683 * be cached globally even for TALK_PROGRESSIVE_LOAD because the
629 if (get_clip(VOICE_PAUSE, &silence)) 684 * VOICE_PAUSE clip is specially handled */
630 goto load_err_free; 685 get_clip(VOICE_PAUSE, &silence);
631 686
632 /* not an error if this fails here, might try again when the 687 /* not an error if this fails here, might try again when the
633 * actual thumbnails are attempted to be played back */ 688 * actual thumbnails are attempted to be played back */
634 alloc_thumbnail_buf(); 689 alloc_thumbnail_buf();
635 690
636 return true; 691 return true;
637
638load_err_free:
639 index_handle = core_free(index_handle);
640 return false;
641} 692}
642 693
643/* most, if not all, clips should be well below 32k (largest in english.lang is 694/* most, if not all, clips should be well below 32k (largest in english.lang is
@@ -659,11 +710,8 @@ static void* commit_transfer(struct queue_entry *qe, size_t *size)
659 sent = MIN((size_t)sent, sizeof(commit_buffer)); 710 sent = MIN((size_t)sent, sizeof(commit_buffer));
660 switch (qe->type) 711 switch (qe->type)
661 { 712 {
662 case TALK_OFFSET: buf = core_get_data(talk_handle) + offset; break;
663 case THUMB_OFFSET: buf = core_get_data(thumb_handle) + offset; break;
664#ifdef TALK_PARTIAL_LOAD
665 case TALK_HANDLE: buf = buflib_get_data(&clip_ctx, offset); break; 713 case TALK_HANDLE: buf = buflib_get_data(&clip_ctx, offset); break;
666#endif 714 case THUMB_OFFSET: buf = core_get_data(thumb_handle) + offset; break;
667 } 715 }
668 /* adjust buffer position to what has been played already */ 716 /* adjust buffer position to what has been played already */
669 buf += (qe->length - qe->remaining); 717 buf += (qe->length - qe->remaining);
@@ -757,11 +805,8 @@ void talk_force_shutup(void)
757 offset = queue[queue_read].offset; 805 offset = queue[queue_read].offset;
758 switch (queue[queue_read].type) 806 switch (queue[queue_read].type)
759 { 807 {
760 case TALK_OFFSET: end = core_get_data(talk_handle) + offset; break;
761 case THUMB_OFFSET: end = core_get_data(thumb_handle) + offset; break; 808 case THUMB_OFFSET: end = core_get_data(thumb_handle) + offset; break;
762#ifdef TALK_PARTIAL_LOAD
763 case TALK_HANDLE: end = buflib_get_data(&clip_ctx, offset); break; 809 case TALK_HANDLE: end = buflib_get_data(&clip_ctx, offset); break;
764#endif
765 default: end = NULL; /* shut up gcc */ 810 default: end = NULL; /* shut up gcc */
766 } 811 }
767 len = queue[queue_read].length; 812 len = queue[queue_read].length;
@@ -922,64 +967,34 @@ void talk_init(void)
922 if (!load_voicefile_index(filehandle)) 967 if (!load_voicefile_index(filehandle))
923 goto out; 968 goto out;
924 969
925#ifdef TALK_PARTIAL_LOAD 970 /* Now determine the maximum buffer size needed for the voicefile.
926 /* TALK_PARTIAL_LOAD loads the actual clip data later, and not all 971 * The below pretends the entire voicefile would be loaded. The buffer
927 * at once */ 972 * size is eventually capped later on in load_voicefile_data() */
928 unsigned num_clips = voicefile.id1_max + voicefile.id2_max; 973 int num_clips = voicefile.id1_max + voicefile.id2_max;
974 int non_empty = num_clips;
975 int total_size = 0, avg_size;
929 struct clip_entry *clips = core_get_data(index_handle); 976 struct clip_entry *clips = core_get_data(index_handle);
930 int avg_size = clips[0].size; 977 /* check for the average clip size to estimate the maximum number of
931 int real_clips = 1; /* shut up gcc */ 978 * clips the buffer can hold */
932 /* check for the smallest clip size to estimate the max. number of clips 979 for (int i = 0; i<num_clips; i++)
933 * the buffer has to hold */
934 for(unsigned i=1; i<num_clips; i++)
935 { 980 {
936 if (clips[i].size) 981 if (clips[i].size)
937 { /* don't consider empty clips, they are not stored anyway */ 982 total_size += ALIGN_UP(clips[i].size, sizeof(void *));
938 real_clips += 1; 983 else
939 avg_size += clips[i].size; 984 non_empty -= 1;
940 }
941 } 985 }
942 avg_size /= real_clips; 986 avg_size = total_size / non_empty;
943 987 max_clips = MIN((int)(MAX_CLIP_BUFFER_SIZE/avg_size) + 1, non_empty);
944 max_clips = MIN((int)(MAX_CLIP_BUFFER_SIZE/avg_size) + 1, real_clips); 988 voicefile_size = total_size;
945 voicefile_size = MAX_CLIP_BUFFER_SIZE; 989 /* additionally to the clips we need a table to record the age of the clips
946 /* additionally to the clip we need a table to record the age of the clips
947 * so that, when memory is tight, only the most recently used ones are kept */ 990 * so that, when memory is tight, only the most recently used ones are kept */
948 voicefile_size += sizeof(struct clip_cache_metadata) * max_clips; 991 voicefile_size += sizeof(struct clip_cache_metadata) * max_clips;
949 /* compensate a bit for buflib per-alloc overhead */ 992 /* compensate a bit for buflib alloc overhead. */
950 voicefile_size += BUFLIB_ALLOC_OVERHEAD * max_clips; 993 voicefile_size += BUFLIB_ALLOC_OVERHEAD * max_clips + 64;
951 /* cap to the max. number of clips or the size of the available audio
952 * buffer which we grab. We leave some to the rest of the system.
953 * While that reduces our buffer size it improves the chance that
954 * other allocs succeed without disabling voice which would require
955 * reloading the voice from disk (as we do not shrink our buffer when
956 * other code attempts new allocs these would fail) */
957 ssize_t cap = MIN(MAX_CLIP_BUFFER_SIZE, audio_buffer_available() - (64<<10));
958 if (UNLIKELY(cap < 0))
959 {
960 logf("Not enough memory for voice. Disabling...\n");
961 if (index_handle > 0)
962 index_handle = core_free(index_handle);
963 voicefile_size = 0;
964 goto out;
965 }
966 else if (voicefile_size > (size_t)cap)
967 voicefile_size = cap;
968
969#else
970 size_t clips_size;
971 clips_size = (voicefile.id1_max+voicefile.id2_max) * sizeof(struct clip_entry);
972 voicefile_size = filesize(filehandle) - voicefile.table - clips_size;
973 /* load the compressed clip data into memory */
974 if (!load_voicefile_data(filehandle, voicefile_size))
975 {
976 voicefile_size = 0;
977 goto out;
978 }
979#endif
980
981 has_voicefile = true; 994 has_voicefile = true;
982 995
996 load_voicefile_data(filehandle);
997
983#if CONFIG_CODEC == SWCODEC 998#if CONFIG_CODEC == SWCODEC
984 /* Initialize the actual voice clip playback engine as well */ 999 /* Initialize the actual voice clip playback engine as well */
985 if (talk_voice_required()) 1000 if (talk_voice_required())
@@ -1022,7 +1037,7 @@ int talk_id(int32_t id, bool enqueue)
1022 int fd = open_voicefile(); 1037 int fd = open_voicefile();
1023 if (fd < 0 1038 if (fd < 0
1024 || !load_voicefile_index(fd) 1039 || !load_voicefile_index(fd)
1025 || !load_voicefile_data(fd, voicefile_size)) 1040 || !load_voicefile_data(fd))
1026 return -1; 1041 return -1;
1027 } 1042 }
1028 1043
@@ -1561,9 +1576,7 @@ bool talk_get_debug_data(struct talk_debug_data *data)
1561 p_lang = (char *)global_settings.lang_file; 1576 p_lang = (char *)global_settings.lang_file;
1562 1577
1563 struct clip_entry *clips = core_get_data(index_handle); 1578 struct clip_entry *clips = core_get_data(index_handle);
1564#ifdef TALK_PARTIAL_LOAD
1565 int cached = 0; 1579 int cached = 0;
1566#endif
1567 int real_clips = 0; 1580 int real_clips = 0;
1568 1581
1569 strlcpy(data->voicefile, p_lang, sizeof(data->voicefile)); 1582 strlcpy(data->voicefile, p_lang, sizeof(data->voicefile));
@@ -1580,27 +1593,20 @@ bool talk_get_debug_data(struct talk_debug_data *data)
1580 if (size > data->max_clipsize) 1593 if (size > data->max_clipsize)
1581 data->max_clipsize = size; 1594 data->max_clipsize = size;
1582 data->avg_clipsize += size; 1595 data->avg_clipsize += size;
1583#ifdef TALK_PARTIAL_LOAD
1584 if (clips[i].size & LOADED_MASK) 1596 if (clips[i].size & LOADED_MASK)
1585 cached++; 1597 cached++;
1586#endif
1587 } 1598 }
1588 data->avg_clipsize /= real_clips; 1599 data->avg_clipsize /= real_clips;
1589 data->num_empty_clips = data->num_clips - real_clips; 1600 data->num_empty_clips = data->num_clips - real_clips;
1590 data->memory_allocated = sizeof(commit_buffer) + sizeof(voicefile) 1601 data->memory_allocated = sizeof(commit_buffer) + sizeof(voicefile)
1591 + data->num_clips * sizeof(struct clip_entry) 1602 + data->num_clips * sizeof(struct clip_entry)
1592 + voicefile_size + size_for_thumbnail; 1603 + voicebuf_size + size_for_thumbnail;
1593 data->memory_used = data->memory_allocated - size_for_thumbnail + thumbnail_buf_used; 1604 data->memory_used = data->memory_allocated - size_for_thumbnail + thumbnail_buf_used;
1594#ifdef TALK_PARTIAL_LOAD
1595 if (talk_handle > 0) 1605 if (talk_handle > 0)
1596 data->memory_used -= buflib_available(&clip_ctx); 1606 data->memory_used -= buflib_available(&clip_ctx);
1597 data->cached_clips = cached; 1607 data->cached_clips = cached;
1598 data->cache_hits = cache_hits; 1608 data->cache_hits = cache_hits;
1599 data->cache_misses = cache_misses; 1609 data->cache_misses = cache_misses;
1600#else
1601 data->cached_clips = real_clips;
1602 data->cache_hits = data->cache_misses = -1;
1603#endif
1604 1610
1605 return true; 1611 return true;
1606} 1612}