Index: apps/talk.c =================================================================== RCS file: /cvsroot/rockbox/apps/talk.c,v retrieving revision 1.46 diff -u -r1.46 talk.c --- apps/talk.c 25 May 2006 12:45:57 -0000 1.46 +++ apps/talk.c 1 Aug 2006 20:31:28 -0000 @@ -39,6 +39,25 @@ #include "playback.h" #endif + +/* Memory layout varies between targets because the + Archos (MASCODEC) devices cannot mix voice and audio playback + + MASCODEC | MASCODEC | SWCODEC + (playing) | (stopped) | + audiobuf-----------+-----------+-----------audiobuf (original), p_voicefile + audio | voice | voice + |-----------|-----------p_thumbnail + | thumbnail | thumbnail + | |-----------audiobuf (after) + | | audio + audiobufend----------+-----------+-----------audiobufend + + Because of this, on SWCODEC the buffers are allocated when + first required and audiobuf is increased appropriately. +*/ + + /***************** Constants *****************/ #define QUEUE_SIZE 64 /* must be a power of two */ @@ -52,6 +71,10 @@ #define LOADED_MASK 0x80000000 /* MSB */ +#if CONFIG_CODEC == SWCODEC +#define MAX_THUMBNAIL_BUFSIZE 32768 +#endif + /***************** Data types *****************/ @@ -173,11 +196,15 @@ == offsetof(struct voicefile, index)) { p_voicefile = (struct voicefile*)audiobuf; - - /* thumbnail buffer is the remaining space behind */ +#if CONFIG_CODEC == SWCODEC + /* SWCODEC: allocate permanent buffer */ + audiobuf += file_size; +#else + /* MASCODEC: thumbnail buffer is the remaining space behind */ p_thumbnail = audiobuf + file_size; p_thumbnail += (long)p_thumbnail % 2; /* 16-bit align */ size_for_thumbnail = audiobufend - p_thumbnail; +#endif } else goto load_err; @@ -198,7 +225,7 @@ cpu_boost(true); buf = (unsigned char *)(&p_voicefile->index) + (p_voicefile->id1_max + p_voicefile->id2_max) * sizeof(struct clip_entry); - length = file_size - (buf - audiobuf); + length = file_size - (buf - (unsigned char *) p_voicefile); for (i = 0; i < length; i++) { @@ -216,7 +243,7 @@ load_size = (p_voicefile->id1_max + p_voicefile->id2_max) * sizeof(struct clip_entry); got_size = read(filehandle, - audiobuf + offsetof(struct voicefile, index), load_size); + (unsigned char *) p_voicefile + offsetof(struct voicefile, index), load_size); if (got_size != load_size) /* read error */ goto load_err; #else @@ -280,7 +307,7 @@ } else if (p_silence != NULL /* silence clip available */ && p_lastclip != p_silence /* previous clip wasn't silence */ - && p_lastclip < p_thumbnail) /* ..and not a thumbnail */ + && (p_thumbnail == NULL || p_lastclip < p_thumbnail)) /* ..and not a thumbnail */ { /* add silence clip when queue runs empty playing a voice clip */ queue[queue_write].buf = p_silence; queue[queue_write].len = silence_len; @@ -424,7 +451,7 @@ clipsize = p_voicefile->index[id].size; if (clipsize == 0) /* clip not included in voicefile */ return NULL; - clipbuf = audiobuf + p_voicefile->index[id].offset; + clipbuf = (unsigned char *) p_voicefile + p_voicefile->index[id].offset; #ifdef HAVE_MMC /* dynamic loading, on demand */ if (!(clipsize & LOADED_MASK)) @@ -451,8 +478,13 @@ { queue_write = queue_read = 0; /* reset the queue */ p_voicefile = NULL; /* indicate no voicefile (trashed) */ - p_thumbnail = audiobuf; /* whole space for thumbnail */ +#if CONFIG_CODEC == SWCODEC + p_thumbnail = NULL; /* will be allocated later */ + size_for_thumbnail = 0; +#else + p_thumbnail = audiobuf; /* whole buffer for thumbnail */ size_for_thumbnail = audiobufend - audiobuf; +#endif p_silence = NULL; /* pause clip not accessible */ } @@ -566,6 +598,19 @@ if (audio_status()) /* busy, buffer in use */ return -1; +#if CONFIG_CODEC == SWCODEC + /* Allocate a thumbnail buffer if required */ + if (p_thumbnail == NULL) + { + p_thumbnail = audiobuf; + p_thumbnail += (long)p_thumbnail % 2; /* 16-bit align */ + size_for_thumbnail = audiobufend - audiobuf; + if (size_for_thumbnail > MAX_THUMBNAIL_BUFSIZE) + size_for_thumbnail = MAX_THUMBNAIL_BUFSIZE; + audiobuf = p_thumbnail + size_for_thumbnail; + } +#endif + if (p_thumbnail == NULL || size_for_thumbnail <= 0) return -1; @@ -587,7 +632,7 @@ /* ToDo: find audio, skip ID headers and trailers */ - if (size) + if (size != 0 && size != size_for_thumbnail) /* Don't play missing or truncated clips */ { #if CONFIG_CODEC != SWCODEC bitswap(p_thumbnail, size);