summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2014-01-21 23:22:37 +0100
committerThomas Martitz <kugel@rockbox.org>2014-02-02 19:40:39 +0100
commite5eb74592eeff013d818ff0c56692b220dd53fbc (patch)
treee954624b31806dc57f59c8d755d866c6abc9f8f9
parentaf02a674c539ee76260be543c000637ffa6ce2af (diff)
downloadrockbox-e5eb74592eeff013d818ff0c56692b220dd53fbc.tar.gz
rockbox-e5eb74592eeff013d818ff0c56692b220dd53fbc.zip
talk/voice: Reduce the size of the commit buffer.
The voice engine can now request more voice data during decoding, it does not require the entire clip to be available before start of decoding anymore. Therefore the commit buffer does not need to hold an entire voice clip anymore, and can be made greatly smaller. Change-Id: I3eca9026448e725b9b8d0dae1efca0ad185371da
-rw-r--r--apps/talk.c17
-rw-r--r--apps/voice_thread.c25
2 files changed, 36 insertions, 6 deletions
diff --git a/apps/talk.c b/apps/talk.c
index a49de09e84..ab9ca8c495 100644
--- a/apps/talk.c
+++ b/apps/talk.c
@@ -636,11 +636,10 @@ static bool load_voicefile_data(int fd)
636 return true; 636 return true;
637} 637}
638 638
639/* most, if not all, clips should be well below 32k (largest in english.lang is 639/* Use a static buffer to avoid difficulties with buflib during DMA
640 * 4.5K). Currently there is a problem with voice decoding such that clips 640 * (hwcodec)/buffer passing to the voice_thread (swcodec). Clips
641 * cannot be decoded in chunks. Once that is resolved this buffer could be 641 * can be played in chunks so the size is not that important */
642 * smaller and clips be decoded in multiple chunks */ 642static unsigned char commit_buffer[1<<10];
643static unsigned char commit_buffer[32<<10];
644 643
645static void* commit_transfer(struct queue_entry *qe, size_t *size) 644static void* commit_transfer(struct queue_entry *qe, size_t *size)
646{ 645{
@@ -658,7 +657,6 @@ static void* commit_transfer(struct queue_entry *qe, size_t *size)
658 memcpy(bufpos, buf, sent); 657 memcpy(bufpos, buf, sent);
659 *size = sent; 658 *size = sent;
660 659
661
662 return commit_buffer; 660 return commit_buffer;
663} 661}
664 662
@@ -674,6 +672,13 @@ static inline bool is_silence(struct queue_entry *qe)
674static void mp3_callback(const void** start, size_t* size) 672static void mp3_callback(const void** start, size_t* size)
675{ 673{
676 struct queue_entry *qe = &queue[queue_read]; 674 struct queue_entry *qe = &queue[queue_read];
675#if CONFIG_CODEC == SWCODEC
676 /* voice_thread.c hints us how many of the buffer we provided it actually
677 * consumed. Because buffers have to be frame-aligned for speex
678 * it might be less than what we presented */
679 if (*size)
680 sent = *size;
681#endif
677 qe->remaining -= sent; /* we completed this */ 682 qe->remaining -= sent; /* we completed this */
678 683
679 if (qe->remaining > 0) /* current clip not finished? */ 684 if (qe->remaining > 0) /* current clip not finished? */
diff --git a/apps/voice_thread.c b/apps/voice_thread.c
index 72ecb3741e..dcb7eef224 100644
--- a/apps/voice_thread.c
+++ b/apps/voice_thread.c
@@ -63,9 +63,17 @@
63 latency */ 63 latency */
64#define PRIORITY_VOICE (PRIORITY_PLAYBACK-4) 64#define PRIORITY_VOICE (PRIORITY_PLAYBACK-4)
65 65
66/* A speex frame generally consists of 20ms of audio
67 * (http://www.speex.org/docs/manual/speex-manual/node10.html)
68 * for wideband mode this results in 320 samples of decoded PCM.
69 */
66#define VOICE_FRAME_COUNT 320 /* Samples / frame */ 70#define VOICE_FRAME_COUNT 320 /* Samples / frame */
67#define VOICE_SAMPLE_RATE 16000 /* Sample rate in HZ */ 71#define VOICE_SAMPLE_RATE 16000 /* Sample rate in HZ */
68#define VOICE_SAMPLE_DEPTH 16 /* Sample depth in bits */ 72#define VOICE_SAMPLE_DEPTH 16 /* Sample depth in bits */
73/* The max. wideband bitrate is 42.4 kbps
74 * (http://www.speex.org/docs/manual/speex-manual/node11.html). For 20ms
75 * this gives a maximum of 106 bytes for an encoded speex frame */
76#define VOICE_MAX_ENCODED_FRAME_SIZE 106
69 77
70/* Voice thread variables */ 78/* Voice thread variables */
71static unsigned int voice_thread_id = 0; 79static unsigned int voice_thread_id = 0;
@@ -449,6 +457,23 @@ static enum voice_state voice_decode(struct voice_thread_data *td)
449 } 457 }
450 else 458 else
451 { 459 {
460 if (td->vi.size > VOICE_MAX_ENCODED_FRAME_SIZE
461 && td->bits.charPtr > (td->vi.size - VOICE_MAX_ENCODED_FRAME_SIZE)
462 && td->vi.get_more != NULL)
463 {
464 /* request more data _before_ running out of data (requesting
465 * more after the fact prevents speex from successful decoding)
466 * place a hint telling the callback how much of the
467 * previous buffer we have consumed such that it can rewind
468 * as necessary */
469 int bitPtr = td->bits.bitPtr;
470 td->vi.size = td->bits.charPtr;
471 td->vi.get_more(&td->vi.start, &td->vi.size);
472 speex_bits_set_bit_buffer(&td->bits, (void *)td->vi.start,
473 td->vi.size);
474 td->bits.bitPtr = bitPtr;
475 }
476
452 yield(); 477 yield();
453 478
454 /* Output the decoded frame */ 479 /* Output the decoded frame */