summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2006-08-01 22:02:47 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2006-08-01 22:02:47 +0000
commit30c618cd96f3fb1de03254c891c4c9ca7f8a7355 (patch)
tree3ff19e2cca984c582de9cd517782d952f2a47a51 /apps
parent73c283e969916b4ff918a7ff9ccb15038fb2ff18 (diff)
downloadrockbox-30c618cd96f3fb1de03254c891c4c9ca7f8a7355.tar.gz
rockbox-30c618cd96f3fb1de03254c891c4c9ca7f8a7355.zip
Patch #5690 by Steve Bavin - Fix for memory corruption when using .talk clips
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10396 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/talk.c56
-rw-r--r--apps/tree.c4
2 files changed, 50 insertions, 10 deletions
diff --git a/apps/talk.c b/apps/talk.c
index 1a1cb81cd1..736c68c7b4 100644
--- a/apps/talk.c
+++ b/apps/talk.c
@@ -39,6 +39,23 @@
39#include "playback.h" 39#include "playback.h"
40#endif 40#endif
41 41
42
43/* Memory layout varies between targets because the
44 Archos (MASCODEC) devices cannot mix voice and audio playback
45
46 MASCODEC | MASCODEC | SWCODEC
47 (playing) | (stopped) |
48 audiobuf-----------+-----------+-----------
49 audio | voice | thumbnail
50 |-----------|-----------
51 | thumbnail | voice
52 | |-----------
53 | | audio
54 audiobufend----------+-----------+-----------
55
56 SWCODEC allocates dedicated buffers, MASCODEC reuses audiobuf. */
57
58
42/***************** Constants *****************/ 59/***************** Constants *****************/
43 60
44#define QUEUE_SIZE 64 /* must be a power of two */ 61#define QUEUE_SIZE 64 /* must be a power of two */
@@ -52,6 +69,10 @@ const char* const file_thumbnail_ext = ".talk";
52 69
53#define LOADED_MASK 0x80000000 /* MSB */ 70#define LOADED_MASK 0x80000000 /* MSB */
54 71
72#if CONFIG_CODEC == SWCODEC
73#define MAX_THUMBNAIL_BUFSIZE 32768
74#endif
75
55 76
56/***************** Data types *****************/ 77/***************** Data types *****************/
57 78
@@ -172,12 +193,16 @@ static void load_voicefile(void)
172 if (((struct voicefile*)audiobuf)->table /* format check */ 193 if (((struct voicefile*)audiobuf)->table /* format check */
173 == offsetof(struct voicefile, index)) 194 == offsetof(struct voicefile, index))
174 { 195 {
196#if CONFIG_CODEC == SWCODEC
197 /* SWCODEC: allocate permanent buffer */
198 p_voicefile = (struct voicefile*)buffer_alloc(file_size);
199#else
200 /* MASCODEC: now use audiobuf for voice then thumbnail */
175 p_voicefile = (struct voicefile*)audiobuf; 201 p_voicefile = (struct voicefile*)audiobuf;
176
177 /* thumbnail buffer is the remaining space behind */
178 p_thumbnail = audiobuf + file_size; 202 p_thumbnail = audiobuf + file_size;
179 p_thumbnail += (long)p_thumbnail % 2; /* 16-bit align */ 203 p_thumbnail += (long)p_thumbnail % 2; /* 16-bit align */
180 size_for_thumbnail = audiobufend - p_thumbnail; 204 size_for_thumbnail = audiobufend - p_thumbnail;
205#endif
181 } 206 }
182 else 207 else
183 goto load_err; 208 goto load_err;
@@ -198,7 +223,7 @@ static void load_voicefile(void)
198 cpu_boost(true); 223 cpu_boost(true);
199 buf = (unsigned char *)(&p_voicefile->index) + 224 buf = (unsigned char *)(&p_voicefile->index) +
200 (p_voicefile->id1_max + p_voicefile->id2_max) * sizeof(struct clip_entry); 225 (p_voicefile->id1_max + p_voicefile->id2_max) * sizeof(struct clip_entry);
201 length = file_size - (buf - audiobuf); 226 length = file_size - (buf - (unsigned char *) p_voicefile);
202 227
203 for (i = 0; i < length; i++) 228 for (i = 0; i < length; i++)
204 { 229 {
@@ -216,7 +241,7 @@ static void load_voicefile(void)
216 load_size = (p_voicefile->id1_max + p_voicefile->id2_max) 241 load_size = (p_voicefile->id1_max + p_voicefile->id2_max)
217 * sizeof(struct clip_entry); 242 * sizeof(struct clip_entry);
218 got_size = read(filehandle, 243 got_size = read(filehandle,
219 audiobuf + offsetof(struct voicefile, index), load_size); 244 (unsigned char *) p_voicefile + offsetof(struct voicefile, index), load_size);
220 if (got_size != load_size) /* read error */ 245 if (got_size != load_size) /* read error */
221 goto load_err; 246 goto load_err;
222#else 247#else
@@ -278,9 +303,9 @@ re_check:
278 curr_hd[1] = p_lastclip[2]; 303 curr_hd[1] = p_lastclip[2];
279 curr_hd[2] = p_lastclip[3]; 304 curr_hd[2] = p_lastclip[3];
280 } 305 }
281 else if (p_silence != NULL /* silence clip available */ 306 else if (p_silence != NULL /* silence clip available */
282 && p_lastclip != p_silence /* previous clip wasn't silence */ 307 && p_lastclip != p_silence /* previous clip wasn't silence */
283 && p_lastclip < p_thumbnail) /* ..and not a thumbnail */ 308 && p_lastclip != p_thumbnail) /* ..or thumbnail */
284 { /* add silence clip when queue runs empty playing a voice clip */ 309 { /* add silence clip when queue runs empty playing a voice clip */
285 queue[queue_write].buf = p_silence; 310 queue[queue_write].buf = p_silence;
286 queue[queue_write].len = silence_len; 311 queue[queue_write].len = silence_len;
@@ -424,7 +449,7 @@ static unsigned char* get_clip(long id, long* p_size)
424 clipsize = p_voicefile->index[id].size; 449 clipsize = p_voicefile->index[id].size;
425 if (clipsize == 0) /* clip not included in voicefile */ 450 if (clipsize == 0) /* clip not included in voicefile */
426 return NULL; 451 return NULL;
427 clipbuf = audiobuf + p_voicefile->index[id].offset; 452 clipbuf = (unsigned char *) p_voicefile + p_voicefile->index[id].offset;
428 453
429#ifdef HAVE_MMC /* dynamic loading, on demand */ 454#ifdef HAVE_MMC /* dynamic loading, on demand */
430 if (!(clipsize & LOADED_MASK)) 455 if (!(clipsize & LOADED_MASK))
@@ -451,8 +476,17 @@ static void reset_state(void)
451{ 476{
452 queue_write = queue_read = 0; /* reset the queue */ 477 queue_write = queue_read = 0; /* reset the queue */
453 p_voicefile = NULL; /* indicate no voicefile (trashed) */ 478 p_voicefile = NULL; /* indicate no voicefile (trashed) */
454 p_thumbnail = audiobuf; /* whole space for thumbnail */ 479#if CONFIG_CODEC == SWCODEC
480 /* Allocate a dedicated thumbnail buffer */
455 size_for_thumbnail = audiobufend - audiobuf; 481 size_for_thumbnail = audiobufend - audiobuf;
482 if (size_for_thumbnail > MAX_THUMBNAIL_BUFSIZE)
483 size_for_thumbnail = MAX_THUMBNAIL_BUFSIZE;
484 p_thumbnail = buffer_alloc(size_for_thumbnail);
485#else
486 /* Just use the audiobuf, without allocating anything */
487 p_thumbnail = audiobuf;
488 size_for_thumbnail = audiobufend - audiobuf;
489#endif
456 p_silence = NULL; /* pause clip not accessible */ 490 p_silence = NULL; /* pause clip not accessible */
457} 491}
458 492
@@ -563,8 +597,10 @@ int talk_file(const char* filename, bool enqueue)
563 int size; 597 int size;
564 struct mp3entry info; 598 struct mp3entry info;
565 599
600#if CONFIG_CODEC != SWCODEC
566 if (audio_status()) /* busy, buffer in use */ 601 if (audio_status()) /* busy, buffer in use */
567 return -1; 602 return -1;
603#endif
568 604
569 if (p_thumbnail == NULL || size_for_thumbnail <= 0) 605 if (p_thumbnail == NULL || size_for_thumbnail <= 0)
570 return -1; 606 return -1;
@@ -587,7 +623,7 @@ int talk_file(const char* filename, bool enqueue)
587 623
588 /* ToDo: find audio, skip ID headers and trailers */ 624 /* ToDo: find audio, skip ID headers and trailers */
589 625
590 if (size) 626 if (size != 0 && size != size_for_thumbnail) /* Don't play missing or truncated clips */
591 { 627 {
592#if CONFIG_CODEC != SWCODEC 628#if CONFIG_CODEC != SWCODEC
593 bitswap(p_thumbnail, size); 629 bitswap(p_thumbnail, size);
diff --git a/apps/tree.c b/apps/tree.c
index 83be023475..7543ceb3f7 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -1306,8 +1306,10 @@ int ft_play_dirname(char* name)
1306 int fd; 1306 int fd;
1307 char dirname_mp3_filename[MAX_PATH+1]; 1307 char dirname_mp3_filename[MAX_PATH+1];
1308 1308
1309#if CONFIG_CODEC != SWCODEC
1309 if (audio_status() & AUDIO_STATUS_PLAY) 1310 if (audio_status() & AUDIO_STATUS_PLAY)
1310 return 0; 1311 return 0;
1312#endif
1311 1313
1312 snprintf(dirname_mp3_filename, sizeof(dirname_mp3_filename), "%s/%s/%s", 1314 snprintf(dirname_mp3_filename, sizeof(dirname_mp3_filename), "%s/%s/%s",
1313 tc.currdir[1] ? tc.currdir : "" , name, 1315 tc.currdir[1] ? tc.currdir : "" , name,
@@ -1334,8 +1336,10 @@ void ft_play_filename(char *dir, char *file)
1334{ 1336{
1335 char name_mp3_filename[MAX_PATH+1]; 1337 char name_mp3_filename[MAX_PATH+1];
1336 1338
1339#if CONFIG_CODEC != SWCODEC
1337 if (audio_status() & AUDIO_STATUS_PLAY) 1340 if (audio_status() & AUDIO_STATUS_PLAY)
1338 return; 1341 return;
1342#endif
1339 1343
1340 if (strcasecmp(&file[strlen(file) - strlen(file_thumbnail_ext)], 1344 if (strcasecmp(&file[strlen(file) - strlen(file_thumbnail_ext)],
1341 file_thumbnail_ext)) 1345 file_thumbnail_ext))