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) return true; } -/* most, if not all, clips should be well below 32k (largest in english.lang is - * 4.5K). Currently there is a problem with voice decoding such that clips - * cannot be decoded in chunks. Once that is resolved this buffer could be - * smaller and clips be decoded in multiple chunks */ -static unsigned char commit_buffer[32<<10]; +/* Use a static buffer to avoid difficulties with buflib during DMA + * (hwcodec)/buffer passing to the voice_thread (swcodec). Clips + * can be played in chunks so the size is not that important */ +static unsigned char commit_buffer[1<<10]; static void* commit_transfer(struct queue_entry *qe, size_t *size) { @@ -658,7 +657,6 @@ static void* commit_transfer(struct queue_entry *qe, size_t *size) memcpy(bufpos, buf, sent); *size = sent; - return commit_buffer; } @@ -674,6 +672,13 @@ static inline bool is_silence(struct queue_entry *qe) static void mp3_callback(const void** start, size_t* size) { struct queue_entry *qe = &queue[queue_read]; +#if CONFIG_CODEC == SWCODEC + /* voice_thread.c hints us how many of the buffer we provided it actually + * consumed. Because buffers have to be frame-aligned for speex + * it might be less than what we presented */ + if (*size) + sent = *size; +#endif qe->remaining -= sent; /* we completed this */ 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 @@ latency */ #define PRIORITY_VOICE (PRIORITY_PLAYBACK-4) +/* A speex frame generally consists of 20ms of audio + * (http://www.speex.org/docs/manual/speex-manual/node10.html) + * for wideband mode this results in 320 samples of decoded PCM. + */ #define VOICE_FRAME_COUNT 320 /* Samples / frame */ #define VOICE_SAMPLE_RATE 16000 /* Sample rate in HZ */ #define VOICE_SAMPLE_DEPTH 16 /* Sample depth in bits */ +/* The max. wideband bitrate is 42.4 kbps + * (http://www.speex.org/docs/manual/speex-manual/node11.html). For 20ms + * this gives a maximum of 106 bytes for an encoded speex frame */ +#define VOICE_MAX_ENCODED_FRAME_SIZE 106 /* Voice thread variables */ static unsigned int voice_thread_id = 0; @@ -449,6 +457,23 @@ static enum voice_state voice_decode(struct voice_thread_data *td) } else { + if (td->vi.size > VOICE_MAX_ENCODED_FRAME_SIZE + && td->bits.charPtr > (td->vi.size - VOICE_MAX_ENCODED_FRAME_SIZE) + && td->vi.get_more != NULL) + { + /* request more data _before_ running out of data (requesting + * more after the fact prevents speex from successful decoding) + * place a hint telling the callback how much of the + * previous buffer we have consumed such that it can rewind + * as necessary */ + int bitPtr = td->bits.bitPtr; + td->vi.size = td->bits.charPtr; + td->vi.get_more(&td->vi.start, &td->vi.size); + speex_bits_set_bit_buffer(&td->bits, (void *)td->vi.start, + td->vi.size); + td->bits.bitPtr = bitPtr; + } + yield(); /* Output the decoded frame */