diff options
author | Thomas Martitz <kugel@rockbox.org> | 2014-01-21 23:22:37 +0100 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2014-02-02 19:40:39 +0100 |
commit | e5eb74592eeff013d818ff0c56692b220dd53fbc (patch) | |
tree | e954624b31806dc57f59c8d755d866c6abc9f8f9 | |
parent | af02a674c539ee76260be543c000637ffa6ce2af (diff) | |
download | rockbox-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.c | 17 | ||||
-rw-r--r-- | apps/voice_thread.c | 25 |
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 */ | 642 | static unsigned char commit_buffer[1<<10]; |
643 | static unsigned char commit_buffer[32<<10]; | ||
644 | 643 | ||
645 | static void* commit_transfer(struct queue_entry *qe, size_t *size) | 644 | static 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) | |||
674 | static void mp3_callback(const void** start, size_t* size) | 672 | static 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 */ |
71 | static unsigned int voice_thread_id = 0; | 79 | static 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 */ |