diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/filetree.c | 1 | ||||
-rw-r--r-- | apps/main.c | 11 | ||||
-rw-r--r-- | apps/menus/main_menu.c | 4 | ||||
-rw-r--r-- | apps/misc.c | 3 | ||||
-rw-r--r-- | apps/mp3data.c | 41 | ||||
-rw-r--r-- | apps/mp3data.h | 30 | ||||
-rw-r--r-- | apps/mpeg.c | 89 | ||||
-rw-r--r-- | apps/playback.c | 45 | ||||
-rw-r--r-- | apps/playback.h | 1 | ||||
-rw-r--r-- | apps/playlist.c | 18 | ||||
-rw-r--r-- | apps/playlist_viewer.c | 3 | ||||
-rw-r--r-- | apps/plugin.c | 8 | ||||
-rw-r--r-- | apps/plugin.h | 8 | ||||
-rw-r--r-- | apps/plugins/vbrfix.c | 5 | ||||
-rw-r--r-- | apps/recorder/pcm_record.c | 2 | ||||
-rw-r--r-- | apps/tagcache.c | 8 | ||||
-rw-r--r-- | apps/talk.c | 111 | ||||
-rw-r--r-- | apps/talk.h | 1 |
18 files changed, 231 insertions, 158 deletions
diff --git a/apps/filetree.c b/apps/filetree.c index a7c989fc5e..1aee80b6b2 100644 --- a/apps/filetree.c +++ b/apps/filetree.c | |||
@@ -600,6 +600,7 @@ int ft_enter(struct tree_context* c) | |||
600 | /* firmware file */ | 600 | /* firmware file */ |
601 | case FILE_ATTR_MOD: | 601 | case FILE_ATTR_MOD: |
602 | splash(0, ID2P(LANG_WAIT)); | 602 | splash(0, ID2P(LANG_WAIT)); |
603 | audio_hard_stop(); | ||
603 | rolo_load(buf); | 604 | rolo_load(buf); |
604 | break; | 605 | break; |
605 | #endif | 606 | #endif |
diff --git a/apps/main.c b/apps/main.c index 0b566b5c01..9cb724562c 100644 --- a/apps/main.c +++ b/apps/main.c | |||
@@ -337,11 +337,11 @@ static void init_tagcache(void) | |||
337 | static void init(void) | 337 | static void init(void) |
338 | { | 338 | { |
339 | system_init(); | 339 | system_init(); |
340 | buffer_init(); | ||
340 | kernel_init(); | 341 | kernel_init(); |
341 | #ifdef APPLICATION | 342 | #ifdef APPLICATION |
342 | paths_init(); | 343 | paths_init(); |
343 | #endif | 344 | #endif |
344 | buffer_init(); | ||
345 | enable_irq(); | 345 | enable_irq(); |
346 | lcd_init(); | 346 | lcd_init(); |
347 | #ifdef HAVE_REMOTE_LCD | 347 | #ifdef HAVE_REMOTE_LCD |
@@ -428,13 +428,7 @@ static void init(void) | |||
428 | #endif | 428 | #endif |
429 | 429 | ||
430 | system_init(); | 430 | system_init(); |
431 | #if defined(IPOD_VIDEO) | 431 | buffer_init(); |
432 | audiobufend=(unsigned char *)audiobufend_lds; | ||
433 | if(MEMORYSIZE==64 && probed_ramsize!=64) | ||
434 | { | ||
435 | audiobufend -= (32<<20); | ||
436 | } | ||
437 | #endif | ||
438 | kernel_init(); | 432 | kernel_init(); |
439 | 433 | ||
440 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ | 434 | #ifdef HAVE_ADJUSTABLE_CPU_FREQ |
@@ -445,7 +439,6 @@ static void init(void) | |||
445 | cpu_boost(true); | 439 | cpu_boost(true); |
446 | #endif | 440 | #endif |
447 | 441 | ||
448 | buffer_init(); | ||
449 | 442 | ||
450 | settings_reset(); | 443 | settings_reset(); |
451 | 444 | ||
diff --git a/apps/menus/main_menu.c b/apps/menus/main_menu.c index 6ee7ba4156..c5758d1274 100644 --- a/apps/menus/main_menu.c +++ b/apps/menus/main_menu.c | |||
@@ -182,7 +182,7 @@ static const char* info_getname(int selected_item, void *data, | |||
182 | 182 | ||
183 | case INFO_BUFFER: /* buffer */ | 183 | case INFO_BUFFER: /* buffer */ |
184 | { | 184 | { |
185 | long kib = (audiobufend - audiobuf) / 1024; /* to KiB */ | 185 | long kib = buffer_available() / 1024; /* to KiB */ |
186 | output_dyn_value(s1, sizeof(s1), kib, kbyte_units, true); | 186 | output_dyn_value(s1, sizeof(s1), kib, kbyte_units, true); |
187 | snprintf(buffer, buffer_len, "%s %s", str(LANG_BUFFER_STAT), s1); | 187 | snprintf(buffer, buffer_len, "%s %s", str(LANG_BUFFER_STAT), s1); |
188 | } | 188 | } |
@@ -272,7 +272,7 @@ static int info_speak_item(int selected_item, void * data) | |||
272 | case INFO_BUFFER: /* buffer */ | 272 | case INFO_BUFFER: /* buffer */ |
273 | { | 273 | { |
274 | talk_id(LANG_BUFFER_STAT, false); | 274 | talk_id(LANG_BUFFER_STAT, false); |
275 | long kib = (audiobufend - audiobuf) / 1024; /* to KiB */ | 275 | long kib = buffer_available() / 1024; /* to KiB */ |
276 | output_dyn_value(NULL, 0, kib, kbyte_units, true); | 276 | output_dyn_value(NULL, 0, kib, kbyte_units, true); |
277 | break; | 277 | break; |
278 | } | 278 | } |
diff --git a/apps/misc.c b/apps/misc.c index fef55d5e2e..d74fe73205 100644 --- a/apps/misc.c +++ b/apps/misc.c | |||
@@ -766,7 +766,10 @@ void check_bootfile(bool do_rolo) | |||
766 | static const struct text_message message={ lines, 2 }; | 766 | static const struct text_message message={ lines, 2 }; |
767 | button_clear_queue(); /* Empty the keyboard buffer */ | 767 | button_clear_queue(); /* Empty the keyboard buffer */ |
768 | if(gui_syncyesno_run(&message, NULL, NULL) == YESNO_YES) | 768 | if(gui_syncyesno_run(&message, NULL, NULL) == YESNO_YES) |
769 | { | ||
770 | audio_hard_stop(); | ||
769 | rolo_load(BOOTDIR "/" BOOTFILE); | 771 | rolo_load(BOOTDIR "/" BOOTFILE); |
772 | } | ||
770 | } | 773 | } |
771 | } | 774 | } |
772 | wrtdate = info.wrtdate; | 775 | wrtdate = info.wrtdate; |
diff --git a/apps/mp3data.c b/apps/mp3data.c index 9fed727609..53f13f4f64 100644 --- a/apps/mp3data.c +++ b/apps/mp3data.c | |||
@@ -311,17 +311,18 @@ unsigned long find_next_frame(int fd, | |||
311 | #ifndef __PCTOOL__ | 311 | #ifndef __PCTOOL__ |
312 | static int fnf_read_index; | 312 | static int fnf_read_index; |
313 | static int fnf_buf_len; | 313 | static int fnf_buf_len; |
314 | static unsigned char *fnf_buf; | ||
314 | 315 | ||
315 | static int buf_getbyte(int fd, unsigned char *c) | 316 | static int buf_getbyte(int fd, unsigned char *c) |
316 | { | 317 | { |
317 | if(fnf_read_index < fnf_buf_len) | 318 | if(fnf_read_index < fnf_buf_len) |
318 | { | 319 | { |
319 | *c = audiobuf[fnf_read_index++]; | 320 | *c = fnf_buf[fnf_read_index++]; |
320 | return 1; | 321 | return 1; |
321 | } | 322 | } |
322 | else | 323 | else |
323 | { | 324 | { |
324 | fnf_buf_len = read(fd, audiobuf, audiobufend - audiobuf); | 325 | fnf_buf_len = read(fd, fnf_buf, fnf_buf_len); |
325 | if(fnf_buf_len < 0) | 326 | if(fnf_buf_len < 0) |
326 | return -1; | 327 | return -1; |
327 | 328 | ||
@@ -329,7 +330,7 @@ static int buf_getbyte(int fd, unsigned char *c) | |||
329 | 330 | ||
330 | if(fnf_buf_len > 0) | 331 | if(fnf_buf_len > 0) |
331 | { | 332 | { |
332 | *c = audiobuf[fnf_read_index++]; | 333 | *c = fnf_buf[fnf_read_index++]; |
333 | return 1; | 334 | return 1; |
334 | } | 335 | } |
335 | else | 336 | else |
@@ -345,7 +346,7 @@ static int buf_seek(int fd, int len) | |||
345 | { | 346 | { |
346 | len = fnf_read_index - fnf_buf_len; | 347 | len = fnf_read_index - fnf_buf_len; |
347 | 348 | ||
348 | fnf_buf_len = read(fd, audiobuf, audiobufend - audiobuf); | 349 | fnf_buf_len = read(fd, fnf_buf, fnf_buf_len); |
349 | if(fnf_buf_len < 0) | 350 | if(fnf_buf_len < 0) |
350 | return -1; | 351 | return -1; |
351 | 352 | ||
@@ -361,9 +362,10 @@ static int buf_seek(int fd, int len) | |||
361 | return 0; | 362 | return 0; |
362 | } | 363 | } |
363 | 364 | ||
364 | static void buf_init(void) | 365 | static void buf_init(unsigned char* buf, size_t buflen) |
365 | { | 366 | { |
366 | fnf_buf_len = 0; | 367 | fnf_buf = buf; |
368 | fnf_buf_len = buflen; | ||
367 | fnf_read_index = 0; | 369 | fnf_read_index = 0; |
368 | } | 370 | } |
369 | 371 | ||
@@ -372,8 +374,9 @@ static unsigned long buf_find_next_frame(int fd, long *offset, long max_offset) | |||
372 | return __find_next_frame(fd, offset, max_offset, 0, buf_getbyte, true); | 374 | return __find_next_frame(fd, offset, max_offset, 0, buf_getbyte, true); |
373 | } | 375 | } |
374 | 376 | ||
375 | static int audiobuflen; | 377 | static size_t mem_buflen; |
376 | static int mem_pos; | 378 | static unsigned char* mem_buf; |
379 | static size_t mem_pos; | ||
377 | static int mem_cnt; | 380 | static int mem_cnt; |
378 | static int mem_maxlen; | 381 | static int mem_maxlen; |
379 | 382 | ||
@@ -381,8 +384,8 @@ static int mem_getbyte(int dummy, unsigned char *c) | |||
381 | { | 384 | { |
382 | dummy = dummy; | 385 | dummy = dummy; |
383 | 386 | ||
384 | *c = audiobuf[mem_pos++]; | 387 | *c = mem_buf[mem_pos++]; |
385 | if(mem_pos >= audiobuflen) | 388 | if(mem_pos >= mem_buflen) |
386 | mem_pos = 0; | 389 | mem_pos = 0; |
387 | 390 | ||
388 | if(mem_cnt++ >= mem_maxlen) | 391 | if(mem_cnt++ >= mem_maxlen) |
@@ -394,9 +397,11 @@ static int mem_getbyte(int dummy, unsigned char *c) | |||
394 | unsigned long mem_find_next_frame(int startpos, | 397 | unsigned long mem_find_next_frame(int startpos, |
395 | long *offset, | 398 | long *offset, |
396 | long max_offset, | 399 | long max_offset, |
397 | unsigned long reference_header) | 400 | unsigned long reference_header, |
401 | unsigned char* buf, size_t buflen) | ||
398 | { | 402 | { |
399 | audiobuflen = audiobufend - audiobuf; | 403 | mem_buf = buf; |
404 | mem_buflen = buflen; | ||
400 | mem_pos = startpos; | 405 | mem_pos = startpos; |
401 | mem_cnt = 0; | 406 | mem_cnt = 0; |
402 | mem_maxlen = max_offset; | 407 | mem_maxlen = max_offset; |
@@ -620,8 +625,9 @@ static void long2bytes(unsigned char *buf, long val) | |||
620 | buf[3] = val & 0xff; | 625 | buf[3] = val & 0xff; |
621 | } | 626 | } |
622 | 627 | ||
623 | int count_mp3_frames(int fd, int startpos, int filesize, | 628 | int count_mp3_frames(int fd, int startpos, int filesize, |
624 | void (*progressfunc)(int)) | 629 | void (*progressfunc)(int), |
630 | unsigned char* buf, size_t buflen) | ||
625 | { | 631 | { |
626 | unsigned long header = 0; | 632 | unsigned long header = 0; |
627 | struct mp3info info; | 633 | struct mp3info info; |
@@ -637,7 +643,7 @@ int count_mp3_frames(int fd, int startpos, int filesize, | |||
637 | if(lseek(fd, startpos, SEEK_SET) < 0) | 643 | if(lseek(fd, startpos, SEEK_SET) < 0) |
638 | return -1; | 644 | return -1; |
639 | 645 | ||
640 | buf_init(); | 646 | buf_init(buf, buflen); |
641 | 647 | ||
642 | /* Find out the total number of frames */ | 648 | /* Find out the total number of frames */ |
643 | num_frames = 0; | 649 | num_frames = 0; |
@@ -687,7 +693,8 @@ static const char cooltext[] = "Rockbox - rocks your box"; | |||
687 | int create_xing_header(int fd, long startpos, long filesize, | 693 | int create_xing_header(int fd, long startpos, long filesize, |
688 | unsigned char *buf, unsigned long num_frames, | 694 | unsigned char *buf, unsigned long num_frames, |
689 | unsigned long rec_time, unsigned long header_template, | 695 | unsigned long rec_time, unsigned long header_template, |
690 | void (*progressfunc)(int), bool generate_toc) | 696 | void (*progressfunc)(int), bool generate_toc, |
697 | unsigned char *tempbuf, size_t tempbuflen ) | ||
691 | { | 698 | { |
692 | struct mp3info info; | 699 | struct mp3info info; |
693 | unsigned char toc[100]; | 700 | unsigned char toc[100]; |
@@ -705,7 +712,7 @@ int create_xing_header(int fd, long startpos, long filesize, | |||
705 | if(generate_toc) | 712 | if(generate_toc) |
706 | { | 713 | { |
707 | lseek(fd, startpos, SEEK_SET); | 714 | lseek(fd, startpos, SEEK_SET); |
708 | buf_init(); | 715 | buf_init(tempbuf, tempbuflen); |
709 | 716 | ||
710 | /* Generate filepos table */ | 717 | /* Generate filepos table */ |
711 | last_pos = 0; | 718 | last_pos = 0; |
diff --git a/apps/mp3data.h b/apps/mp3data.h index edda352aab..762c2f4583 100644 --- a/apps/mp3data.h +++ b/apps/mp3data.h | |||
@@ -26,6 +26,8 @@ | |||
26 | #define MPEG_VERSION2 1 | 26 | #define MPEG_VERSION2 1 |
27 | #define MPEG_VERSION2_5 2 | 27 | #define MPEG_VERSION2_5 2 |
28 | 28 | ||
29 | #include <string.h> /* size_t */ | ||
30 | |||
29 | struct mp3info { | 31 | struct mp3info { |
30 | /* Standard MP3 frame header fields */ | 32 | /* Standard MP3 frame header fields */ |
31 | int version; | 33 | int version; |
@@ -63,23 +65,21 @@ unsigned long find_next_frame(int fd, | |||
63 | unsigned long reference_header); | 65 | unsigned long reference_header); |
64 | unsigned long mem_find_next_frame(int startpos, | 66 | unsigned long mem_find_next_frame(int startpos, |
65 | long *offset, | 67 | long *offset, |
66 | long max_offset, | 68 | long max_offset, |
67 | unsigned long reference_header); | 69 | unsigned long reference_header, |
70 | unsigned char* buf, size_t buflen); | ||
68 | int get_mp3file_info(int fd, | 71 | int get_mp3file_info(int fd, |
69 | struct mp3info *info); | 72 | struct mp3info *info); |
70 | int count_mp3_frames(int fd, | 73 | |
71 | int startpos, | 74 | int count_mp3_frames(int fd, int startpos, int filesize, |
72 | int filesize, | 75 | void (*progressfunc)(int), |
73 | void (*progressfunc)(int)); | 76 | unsigned char* buf, size_t buflen); |
74 | int create_xing_header(int fd, | 77 | |
75 | long startpos, | 78 | int create_xing_header(int fd, long startpos, long filesize, |
76 | long filesize, | 79 | unsigned char *buf, unsigned long num_frames, |
77 | unsigned char *buf, | 80 | unsigned long rec_time, unsigned long header_template, |
78 | unsigned long num_frames, | 81 | void (*progressfunc)(int), bool generate_toc, |
79 | unsigned long rec_time, | 82 | unsigned char *tempbuf, size_t tempbuflen ); |
80 | unsigned long header_template, | ||
81 | void (*progressfunc)(int), | ||
82 | bool generate_toc); | ||
83 | 83 | ||
84 | extern unsigned long bytes2int(unsigned long b0, | 84 | extern unsigned long bytes2int(unsigned long b0, |
85 | unsigned long b1, | 85 | unsigned long b1, |
diff --git a/apps/mpeg.c b/apps/mpeg.c index b11445f947..a0182ad8d2 100644 --- a/apps/mpeg.c +++ b/apps/mpeg.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include "mp3data.h" | 37 | #include "mp3data.h" |
38 | #include "buffer.h" | 38 | #include "buffer.h" |
39 | #include "mp3_playback.h" | 39 | #include "mp3_playback.h" |
40 | #include "talk.h" | ||
40 | #include "sound.h" | 41 | #include "sound.h" |
41 | #include "bitswap.h" | 42 | #include "bitswap.h" |
42 | #include "appevents.h" | 43 | #include "appevents.h" |
@@ -144,19 +145,19 @@ static unsigned int mpeg_errno; | |||
144 | static bool playing = false; /* We are playing an MP3 stream */ | 145 | static bool playing = false; /* We are playing an MP3 stream */ |
145 | static bool is_playing = false; /* We are (attempting to) playing MP3 files */ | 146 | static bool is_playing = false; /* We are (attempting to) playing MP3 files */ |
146 | static bool paused; /* playback is paused */ | 147 | static bool paused; /* playback is paused */ |
148 | static char* mpeg_audiobuf; /* the audio buffer */ | ||
149 | static long audiobuflen; /* length of the audio buffer */ | ||
147 | 150 | ||
148 | #ifdef SIMULATOR | 151 | #ifdef SIMULATOR |
149 | static char mpeg_stack[DEFAULT_STACK_SIZE]; | 152 | static char mpeg_stack[DEFAULT_STACK_SIZE]; |
150 | static struct mp3entry taginfo; | 153 | static struct mp3entry taginfo; |
151 | |||
152 | #else /* !SIMULATOR */ | 154 | #else /* !SIMULATOR */ |
153 | static struct event_queue mpeg_queue SHAREDBSS_ATTR; | 155 | static struct event_queue mpeg_queue SHAREDBSS_ATTR; |
154 | static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)]; | 156 | static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)]; |
155 | 157 | ||
156 | static int audiobuflen; | ||
157 | static int audiobuf_write; | 158 | static int audiobuf_write; |
158 | static int audiobuf_swapwrite; | 159 | static int audiobuf_swapwrite; |
159 | static int audiobuf_read; | 160 | static long audiobuf_read; |
160 | 161 | ||
161 | static int mpeg_file; | 162 | static int mpeg_file; |
162 | 163 | ||
@@ -490,6 +491,18 @@ unsigned long mpeg_get_last_header(void) | |||
490 | #endif /* !SIMULATOR */ | 491 | #endif /* !SIMULATOR */ |
491 | } | 492 | } |
492 | 493 | ||
494 | |||
495 | unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size) | ||
496 | { | ||
497 | (void)talk_buf; /* always grab the voice buffer for now */ | ||
498 | |||
499 | audio_hard_stop(); | ||
500 | if (buffer_size) /* special case for talk_init() */ | ||
501 | return buffer_get_buffer(buffer_size); | ||
502 | return NULL; | ||
503 | } | ||
504 | |||
505 | |||
493 | #ifndef SIMULATOR | 506 | #ifndef SIMULATOR |
494 | /* Send callback events to notify about removing old tracks. */ | 507 | /* Send callback events to notify about removing old tracks. */ |
495 | static void generate_unbuffer_events(void) | 508 | static void generate_unbuffer_events(void) |
@@ -708,7 +721,7 @@ void rec_tick(void) | |||
708 | 721 | ||
709 | xor_b(0x08, &PADRH); /* Set PR inactive */ | 722 | xor_b(0x08, &PADRH); /* Set PR inactive */ |
710 | 723 | ||
711 | audiobuf[audiobuf_write++] = data; | 724 | mpeg_audiobuf[audiobuf_write++] = data; |
712 | 725 | ||
713 | if (audiobuf_write >= audiobuflen) | 726 | if (audiobuf_write >= audiobuflen) |
714 | audiobuf_write = 0; | 727 | audiobuf_write = 0; |
@@ -825,7 +838,7 @@ static void transfer_end(unsigned char** ppbuf, size_t* psize) | |||
825 | } | 838 | } |
826 | 839 | ||
827 | *psize = last_dma_chunk_size & 0xffff; | 840 | *psize = last_dma_chunk_size & 0xffff; |
828 | *ppbuf = audiobuf + audiobuf_read; | 841 | *ppbuf = mpeg_audiobuf + audiobuf_read; |
829 | track = get_trackdata(0); | 842 | track = get_trackdata(0); |
830 | if(track) | 843 | if(track) |
831 | track->id3.offset += last_dma_chunk_size; | 844 | track->id3.offset += last_dma_chunk_size; |
@@ -1128,7 +1141,7 @@ static void start_playback_if_ready(void) | |||
1128 | playing = true; | 1141 | playing = true; |
1129 | 1142 | ||
1130 | last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); | 1143 | last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); |
1131 | mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end); | 1144 | mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end); |
1132 | dma_underrun = false; | 1145 | dma_underrun = false; |
1133 | 1146 | ||
1134 | if (!paused) | 1147 | if (!paused) |
@@ -1173,7 +1186,7 @@ static bool swap_one_chunk(void) | |||
1173 | amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite, | 1186 | amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite, |
1174 | amount_to_swap); | 1187 | amount_to_swap); |
1175 | 1188 | ||
1176 | bitswap(audiobuf + audiobuf_swapwrite, amount_to_swap); | 1189 | bitswap(mpeg_audiobuf + audiobuf_swapwrite, amount_to_swap); |
1177 | 1190 | ||
1178 | audiobuf_swapwrite += amount_to_swap; | 1191 | audiobuf_swapwrite += amount_to_swap; |
1179 | if(audiobuf_swapwrite >= audiobuflen) | 1192 | if(audiobuf_swapwrite >= audiobuflen) |
@@ -1341,7 +1354,7 @@ static void mpeg_thread(void) | |||
1341 | track_change(); | 1354 | track_change(); |
1342 | audiobuf_read = get_trackdata(0)->mempos; | 1355 | audiobuf_read = get_trackdata(0)->mempos; |
1343 | last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); | 1356 | last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); |
1344 | mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end); | 1357 | mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end); |
1345 | dma_underrun = false; | 1358 | dma_underrun = false; |
1346 | last_dma_tick = current_tick; | 1359 | last_dma_tick = current_tick; |
1347 | 1360 | ||
@@ -1501,7 +1514,7 @@ static void mpeg_thread(void) | |||
1501 | /* resume will start at new position */ | 1514 | /* resume will start at new position */ |
1502 | last_dma_chunk_size = | 1515 | last_dma_chunk_size = |
1503 | MIN(0x2000, get_unplayed_space_current_song()); | 1516 | MIN(0x2000, get_unplayed_space_current_song()); |
1504 | mp3_play_data(audiobuf + audiobuf_read, | 1517 | mp3_play_data(mpeg_audiobuf + audiobuf_read, |
1505 | last_dma_chunk_size, transfer_end); | 1518 | last_dma_chunk_size, transfer_end); |
1506 | dma_underrun = false; | 1519 | dma_underrun = false; |
1507 | } | 1520 | } |
@@ -1632,7 +1645,7 @@ static void mpeg_thread(void) | |||
1632 | { | 1645 | { |
1633 | DEBUGF("R\n"); | 1646 | DEBUGF("R\n"); |
1634 | t1 = current_tick; | 1647 | t1 = current_tick; |
1635 | len = read(mpeg_file, audiobuf + audiobuf_write, | 1648 | len = read(mpeg_file, mpeg_audiobuf + audiobuf_write, |
1636 | amount_to_read); | 1649 | amount_to_read); |
1637 | if(len > 0) | 1650 | if(len > 0) |
1638 | { | 1651 | { |
@@ -1659,7 +1672,7 @@ static void mpeg_thread(void) | |||
1659 | if(tagptr >= audiobuflen) | 1672 | if(tagptr >= audiobuflen) |
1660 | tagptr -= audiobuflen; | 1673 | tagptr -= audiobuflen; |
1661 | 1674 | ||
1662 | if(audiobuf[tagptr] != tag[i]) | 1675 | if(mpeg_audiobuf[tagptr] != tag[i]) |
1663 | { | 1676 | { |
1664 | taglen = 0; | 1677 | taglen = 0; |
1665 | break; | 1678 | break; |
@@ -1773,19 +1786,20 @@ static void mpeg_thread(void) | |||
1773 | startpos = prerecord_buffer[startpos].mempos; | 1786 | startpos = prerecord_buffer[startpos].mempos; |
1774 | 1787 | ||
1775 | DEBUGF("Start looking at address %x (%x)\n", | 1788 | DEBUGF("Start looking at address %x (%x)\n", |
1776 | audiobuf+startpos, startpos); | 1789 | mpeg_audiobuf+startpos, startpos); |
1777 | 1790 | ||
1778 | saved_header = mpeg_get_last_header(); | 1791 | saved_header = mpeg_get_last_header(); |
1779 | 1792 | ||
1780 | mem_find_next_frame(startpos, &offset, 1800, | 1793 | mem_find_next_frame(startpos, &offset, 1800, |
1781 | saved_header); | 1794 | saved_header, mpeg_audiobuf, |
1795 | audiobuflen); | ||
1782 | 1796 | ||
1783 | audiobuf_read = startpos + offset; | 1797 | audiobuf_read = startpos + offset; |
1784 | if(audiobuf_read >= audiobuflen) | 1798 | if(audiobuf_read >= audiobuflen) |
1785 | audiobuf_read -= audiobuflen; | 1799 | audiobuf_read -= audiobuflen; |
1786 | 1800 | ||
1787 | DEBUGF("New audiobuf_read address: %x (%x)\n", | 1801 | DEBUGF("New audiobuf_read address: %x (%x)\n", |
1788 | audiobuf+audiobuf_read, audiobuf_read); | 1802 | mpeg_audiobuf+audiobuf_read, audiobuf_read); |
1789 | 1803 | ||
1790 | level = disable_irq_save(); | 1804 | level = disable_irq_save(); |
1791 | num_rec_bytes = get_unsaved_space(); | 1805 | num_rec_bytes = get_unsaved_space(); |
@@ -1894,7 +1908,8 @@ static void mpeg_thread(void) | |||
1894 | save_endpos += audiobuflen; | 1908 | save_endpos += audiobuflen; |
1895 | 1909 | ||
1896 | rc = mem_find_next_frame(save_endpos, &offset, 1800, | 1910 | rc = mem_find_next_frame(save_endpos, &offset, 1800, |
1897 | saved_header); | 1911 | saved_header, mpeg_audiobuf, |
1912 | audiobuflen); | ||
1898 | if (!rc) /* No header found, save whole buffer */ | 1913 | if (!rc) /* No header found, save whole buffer */ |
1899 | offset = 1800; | 1914 | offset = 1800; |
1900 | 1915 | ||
@@ -1936,7 +1951,7 @@ static void mpeg_thread(void) | |||
1936 | #elif MEMORYSIZE == 8 | 1951 | #elif MEMORYSIZE == 8 |
1937 | amount_to_save = MIN(0x100000, amount_to_save); | 1952 | amount_to_save = MIN(0x100000, amount_to_save); |
1938 | #endif | 1953 | #endif |
1939 | rc = write(mpeg_file, audiobuf + audiobuf_read, | 1954 | rc = write(mpeg_file, mpeg_audiobuf + audiobuf_read, |
1940 | amount_to_save); | 1955 | amount_to_save); |
1941 | if (rc < 0) | 1956 | if (rc < 0) |
1942 | { | 1957 | { |
@@ -2256,21 +2271,21 @@ static void prepend_header(void) | |||
2256 | if(audiobuf_read < 0) | 2271 | if(audiobuf_read < 0) |
2257 | { | 2272 | { |
2258 | /* Clear the bottom half */ | 2273 | /* Clear the bottom half */ |
2259 | memset(audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE); | 2274 | memset(mpeg_audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE); |
2260 | 2275 | ||
2261 | /* And the top half */ | 2276 | /* And the top half */ |
2262 | audiobuf_read += audiobuflen; | 2277 | audiobuf_read += audiobuflen; |
2263 | memset(audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read); | 2278 | memset(mpeg_audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read); |
2264 | } | 2279 | } |
2265 | else | 2280 | else |
2266 | { | 2281 | { |
2267 | memset(audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE); | 2282 | memset(mpeg_audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE); |
2268 | } | 2283 | } |
2269 | /* Copy the empty ID3 header */ | 2284 | /* Copy the empty ID3 header */ |
2270 | startpos = audiobuf_read; | 2285 | startpos = audiobuf_read; |
2271 | for(i = 0; i < sizeof(empty_id3_header); i++) | 2286 | for(i = 0; i < sizeof(empty_id3_header); i++) |
2272 | { | 2287 | { |
2273 | audiobuf[startpos++] = empty_id3_header[i]; | 2288 | mpeg_audiobuf[startpos++] = empty_id3_header[i]; |
2274 | if(startpos == audiobuflen) | 2289 | if(startpos == audiobuflen) |
2275 | startpos = 0; | 2290 | startpos = 0; |
2276 | } | 2291 | } |
@@ -2297,7 +2312,8 @@ static void update_header(void) | |||
2297 | /* saved_header is saved right before stopping the MAS */ | 2312 | /* saved_header is saved right before stopping the MAS */ |
2298 | framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer, | 2313 | framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer, |
2299 | frames, last_rec_time * (1000/HZ), | 2314 | frames, last_rec_time * (1000/HZ), |
2300 | saved_header, NULL, false); | 2315 | saved_header, NULL, false, |
2316 | mpeg_audiobuf, audiobuflen); | ||
2301 | 2317 | ||
2302 | lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET); | 2318 | lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET); |
2303 | write(fd, xing_buffer, framelen); | 2319 | write(fd, xing_buffer, framelen); |
@@ -2645,8 +2661,22 @@ void audio_set_recording_options(struct audio_recording_options *options) | |||
2645 | #endif /* SIMULATOR */ | 2661 | #endif /* SIMULATOR */ |
2646 | #endif /* CONFIG_CODEC == MAS3587F */ | 2662 | #endif /* CONFIG_CODEC == MAS3587F */ |
2647 | 2663 | ||
2664 | static void audio_reset_buffer(void) | ||
2665 | { | ||
2666 | size_t bufsize; /* dont break strict-aliasing */ | ||
2667 | talk_buffer_steal(); /* will use the mp3 buffer */ | ||
2668 | |||
2669 | /* release buffer on behalf of any audio_get_buffer() caller, | ||
2670 | * non-fatal if there was none */ | ||
2671 | buffer_release_buffer(0); | ||
2672 | /* re-aquire */ | ||
2673 | mpeg_audiobuf = buffer_get_buffer(&bufsize); | ||
2674 | audiobuflen = bufsize; | ||
2675 | } | ||
2676 | |||
2648 | void audio_play(long offset) | 2677 | void audio_play(long offset) |
2649 | { | 2678 | { |
2679 | audio_reset_buffer(); | ||
2650 | #ifdef SIMULATOR | 2680 | #ifdef SIMULATOR |
2651 | char name_buf[MAX_PATH+1]; | 2681 | char name_buf[MAX_PATH+1]; |
2652 | const char* trackname; | 2682 | const char* trackname; |
@@ -2676,7 +2706,6 @@ void audio_play(long offset) | |||
2676 | } while(1); | 2706 | } while(1); |
2677 | #else /* !SIMULATOR */ | 2707 | #else /* !SIMULATOR */ |
2678 | is_playing = true; | 2708 | is_playing = true; |
2679 | |||
2680 | queue_post(&mpeg_queue, MPEG_PLAY, offset); | 2709 | queue_post(&mpeg_queue, MPEG_PLAY, offset); |
2681 | #endif /* !SIMULATOR */ | 2710 | #endif /* !SIMULATOR */ |
2682 | 2711 | ||
@@ -2700,6 +2729,8 @@ void audio_stop(void) | |||
2700 | is_playing = false; | 2729 | is_playing = false; |
2701 | playing = false; | 2730 | playing = false; |
2702 | #endif /* SIMULATOR */ | 2731 | #endif /* SIMULATOR */ |
2732 | /* give voice our entire buffer */ | ||
2733 | talkbuf_init(mpeg_audiobuf); | ||
2703 | } | 2734 | } |
2704 | 2735 | ||
2705 | /* dummy */ | 2736 | /* dummy */ |
@@ -2708,6 +2739,14 @@ void audio_stop_recording(void) | |||
2708 | audio_stop(); | 2739 | audio_stop(); |
2709 | } | 2740 | } |
2710 | 2741 | ||
2742 | void audio_hard_stop(void) | ||
2743 | { | ||
2744 | audio_stop(); | ||
2745 | /* tell voice we obtain the buffer before freeing */ | ||
2746 | talk_buffer_steal(); | ||
2747 | buffer_release_buffer(0); | ||
2748 | } | ||
2749 | |||
2711 | void audio_pause(void) | 2750 | void audio_pause(void) |
2712 | { | 2751 | { |
2713 | #ifndef SIMULATOR | 2752 | #ifndef SIMULATOR |
@@ -2864,8 +2903,12 @@ void audio_init(void) | |||
2864 | if (global_settings.cuesheet) | 2903 | if (global_settings.cuesheet) |
2865 | curr_cuesheet = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet)); | 2904 | curr_cuesheet = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet)); |
2866 | 2905 | ||
2906 | size_t bufsize; /* don't break strict-aliasing */ | ||
2907 | mpeg_audiobuf = buffer_get_buffer(&bufsize); | ||
2908 | audiobuflen = bufsize; | ||
2909 | /* give voice buffer until we start to play */ | ||
2910 | talkbuf_init(mpeg_audiobuf); | ||
2867 | #ifndef SIMULATOR | 2911 | #ifndef SIMULATOR |
2868 | audiobuflen = audiobufend - audiobuf; | ||
2869 | queue_init(&mpeg_queue, true); | 2912 | queue_init(&mpeg_queue, true); |
2870 | #endif /* !SIMULATOR */ | 2913 | #endif /* !SIMULATOR */ |
2871 | create_thread(mpeg_thread, mpeg_stack, | 2914 | create_thread(mpeg_thread, mpeg_stack, |
diff --git a/apps/playback.c b/apps/playback.c index fe9bd579d4..3f6ee71ad7 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -744,16 +744,25 @@ static void audio_reset_buffer(void) | |||
744 | /* see audio_get_recording_buffer if this is modified */ | 744 | /* see audio_get_recording_buffer if this is modified */ |
745 | logf("%s()", __func__); | 745 | logf("%s()", __func__); |
746 | 746 | ||
747 | /* release the buffer on behalf of any caller of audio_get_buffer() */ | ||
748 | buffer_release_buffer(0); | ||
749 | |||
747 | /* If the setup of anything allocated before the file buffer is | 750 | /* If the setup of anything allocated before the file buffer is |
748 | changed, do check the adjustments after the buffer_alloc call | 751 | changed, do check the adjustments after the buffer_alloc call |
749 | as it will likely be affected and need sliding over */ | 752 | as it will likely be affected and need sliding over */ |
750 | 753 | ||
751 | /* Initially set up file buffer as all space available */ | 754 | /* Initially set up file buffer as all space available */ |
752 | unsigned char *filebuf = audiobuf + talk_get_bufsize(); | 755 | size_t filebuflen, allocsize; |
753 | size_t filebuflen = audiobufend - filebuf; | 756 | unsigned char *filebuf = buffer_get_buffer(&filebuflen); |
754 | size_t allocsize; | ||
755 | 757 | ||
756 | ALIGN_BUFFER(filebuf, filebuflen, sizeof (intptr_t)); | 758 | /* Subtract whatever voice needs */ |
759 | allocsize = talkbuf_init(filebuf); | ||
760 | allocsize = ALIGN_UP(allocsize, sizeof (intptr_t)); | ||
761 | if (allocsize > filebuflen) | ||
762 | goto bufpanic; | ||
763 | |||
764 | filebuf += allocsize; | ||
765 | filebuflen -= allocsize; | ||
757 | 766 | ||
758 | if (talk_voice_required()) | 767 | if (talk_voice_required()) |
759 | { | 768 | { |
@@ -3335,6 +3344,7 @@ void audio_hard_stop(void) | |||
3335 | #ifdef PLAYBACK_VOICE | 3344 | #ifdef PLAYBACK_VOICE |
3336 | voice_stop(); | 3345 | voice_stop(); |
3337 | #endif | 3346 | #endif |
3347 | buffer_release_buffer(0); | ||
3338 | } | 3348 | } |
3339 | 3349 | ||
3340 | /* Resume playback if paused */ | 3350 | /* Resume playback if paused */ |
@@ -3441,7 +3451,7 @@ void audio_flush_and_reload_tracks(void) | |||
3441 | voicing */ | 3451 | voicing */ |
3442 | unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size) | 3452 | unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size) |
3443 | { | 3453 | { |
3444 | unsigned char *buf, *end; | 3454 | unsigned char *buf; |
3445 | 3455 | ||
3446 | if (audio_is_initialized) | 3456 | if (audio_is_initialized) |
3447 | { | 3457 | { |
@@ -3461,7 +3471,7 @@ unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size) | |||
3461 | || !talk_voice_required()) | 3471 | || !talk_voice_required()) |
3462 | { | 3472 | { |
3463 | logf("get buffer: talk, audio"); | 3473 | logf("get buffer: talk, audio"); |
3464 | /* Ok to use everything from audiobuf to audiobufend - voice is loaded, | 3474 | /* Ok to use everything from audiobuf - voice is loaded, |
3465 | the talk buffer is not needed because voice isn't being used, or | 3475 | the talk buffer is not needed because voice isn't being used, or |
3466 | could be AUDIOBUF_STATE_TRASHED already. If state is | 3476 | could be AUDIOBUF_STATE_TRASHED already. If state is |
3467 | AUDIOBUF_STATE_VOICED_ONLY, no problem as long as memory isn't | 3477 | AUDIOBUF_STATE_VOICED_ONLY, no problem as long as memory isn't |
@@ -3474,9 +3484,7 @@ unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size) | |||
3474 | talk_buffer_steal(); | 3484 | talk_buffer_steal(); |
3475 | buffer_state = AUDIOBUF_STATE_TRASHED; | 3485 | buffer_state = AUDIOBUF_STATE_TRASHED; |
3476 | } | 3486 | } |
3477 | 3487 | buf = buffer_get_buffer(buffer_size); | |
3478 | buf = audiobuf; | ||
3479 | end = audiobufend; | ||
3480 | } | 3488 | } |
3481 | else | 3489 | else |
3482 | { | 3490 | { |
@@ -3485,14 +3493,18 @@ unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size) | |||
3485 | /* Skip talk buffer and move pcm buffer to end to maximize available | 3493 | /* Skip talk buffer and move pcm buffer to end to maximize available |
3486 | contiguous memory - no audio running means voice will not need the | 3494 | contiguous memory - no audio running means voice will not need the |
3487 | swap space */ | 3495 | swap space */ |
3496 | size_t siz, talkbuf_size; | ||
3488 | logf("get buffer: audio"); | 3497 | logf("get buffer: audio"); |
3489 | buf = audiobuf + talk_get_bufsize(); | 3498 | /* call buffer_get_buffer() to make use of the locking mechanism */ |
3490 | end = audiobufend - voicebuf_init(audiobufend); | 3499 | buf = buffer_get_buffer(&siz); |
3500 | buf += talkbuf_size = talkbuf_init(buf); | ||
3501 | siz -= talkbuf_size; | ||
3502 | siz -= voicebuf_init(buf + siz); | ||
3503 | *buffer_size = siz; | ||
3504 | |||
3491 | buffer_state = AUDIOBUF_STATE_VOICED_ONLY; | 3505 | buffer_state = AUDIOBUF_STATE_VOICED_ONLY; |
3492 | } | 3506 | } |
3493 | 3507 | ||
3494 | *buffer_size = end - buf; | ||
3495 | |||
3496 | return buf; | 3508 | return buf; |
3497 | } | 3509 | } |
3498 | 3510 | ||
@@ -3500,14 +3512,11 @@ unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size) | |||
3500 | /* Stop audio, voice and obtain all available buffer space */ | 3512 | /* Stop audio, voice and obtain all available buffer space */ |
3501 | unsigned char * audio_get_recording_buffer(size_t *buffer_size) | 3513 | unsigned char * audio_get_recording_buffer(size_t *buffer_size) |
3502 | { | 3514 | { |
3503 | audio_hard_stop(); | ||
3504 | talk_buffer_steal(); | 3515 | talk_buffer_steal(); |
3516 | audio_hard_stop(); | ||
3505 | 3517 | ||
3506 | unsigned char *end = audiobufend; | ||
3507 | buffer_state = AUDIOBUF_STATE_TRASHED; | 3518 | buffer_state = AUDIOBUF_STATE_TRASHED; |
3508 | *buffer_size = end - audiobuf; | 3519 | return buffer_get_buffer(buffer_size); |
3509 | |||
3510 | return (unsigned char *)audiobuf; | ||
3511 | } | 3520 | } |
3512 | #endif /* HAVE_RECORDING */ | 3521 | #endif /* HAVE_RECORDING */ |
3513 | 3522 | ||
diff --git a/apps/playback.h b/apps/playback.h index ea8718089f..793055f98c 100644 --- a/apps/playback.h +++ b/apps/playback.h | |||
@@ -75,7 +75,6 @@ int audio_track_count(void); | |||
75 | long audio_filebufused(void); | 75 | long audio_filebufused(void); |
76 | void audio_pre_ff_rewind(void); | 76 | void audio_pre_ff_rewind(void); |
77 | void audio_skip(int direction); | 77 | void audio_skip(int direction); |
78 | void audio_hard_stop(void); /* Stops audio from serving playback */ | ||
79 | 78 | ||
80 | void audio_set_cuesheet(int enable); | 79 | void audio_set_cuesheet(int enable); |
81 | #ifdef HAVE_CROSSFADE | 80 | #ifdef HAVE_CROSSFADE |
diff --git a/apps/playlist.c b/apps/playlist.c index 564cd03d90..8334260242 100644 --- a/apps/playlist.c +++ b/apps/playlist.c | |||
@@ -533,13 +533,7 @@ static int add_indices_to_playlist(struct playlist_info* playlist, | |||
533 | { | 533 | { |
534 | /* use mp3 buffer for maximum load speed */ | 534 | /* use mp3 buffer for maximum load speed */ |
535 | audio_stop(); | 535 | audio_stop(); |
536 | #if CONFIG_CODEC != SWCODEC | 536 | buffer = audio_get_buffer(false, &buflen); |
537 | talk_buffer_steal(); /* we use the mp3 buffer, need to tell */ | ||
538 | buflen = (audiobufend - audiobuf); | ||
539 | buffer = (char *)audiobuf; | ||
540 | #else | ||
541 | buffer = (char *)audio_get_buffer(false, &buflen); | ||
542 | #endif | ||
543 | } | 537 | } |
544 | 538 | ||
545 | store_index = true; | 539 | store_index = true; |
@@ -2018,13 +2012,7 @@ int playlist_resume(void) | |||
2018 | bool sorted = true; | 2012 | bool sorted = true; |
2019 | 2013 | ||
2020 | /* use mp3 buffer for maximum load speed */ | 2014 | /* use mp3 buffer for maximum load speed */ |
2021 | #if CONFIG_CODEC != SWCODEC | ||
2022 | talk_buffer_steal(); /* we use the mp3 buffer, need to tell */ | ||
2023 | buflen = (audiobufend - audiobuf); | ||
2024 | buffer = (char *)audiobuf; | ||
2025 | #else | ||
2026 | buffer = (char *)audio_get_buffer(false, &buflen); | 2015 | buffer = (char *)audio_get_buffer(false, &buflen); |
2027 | #endif | ||
2028 | 2016 | ||
2029 | empty_playlist(playlist, true); | 2017 | empty_playlist(playlist, true); |
2030 | 2018 | ||
@@ -2449,10 +2437,6 @@ void playlist_start(int start_index, int offset) | |||
2449 | 2437 | ||
2450 | playlist->index = start_index; | 2438 | playlist->index = start_index; |
2451 | 2439 | ||
2452 | #if CONFIG_CODEC != SWCODEC | ||
2453 | talk_buffer_steal(); /* will use the mp3 buffer */ | ||
2454 | #endif | ||
2455 | |||
2456 | playlist->started = true; | 2440 | playlist->started = true; |
2457 | sync_control(playlist, false); | 2441 | sync_control(playlist, false); |
2458 | audio_play(offset); | 2442 | audio_play(offset); |
diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c index 803fba9765..43c0c0142e 100644 --- a/apps/playlist_viewer.c +++ b/apps/playlist_viewer.c | |||
@@ -493,9 +493,6 @@ static int onplay_menu(int index) | |||
493 | if (current_track->display_index!=viewer.num_tracks || | 493 | if (current_track->display_index!=viewer.num_tracks || |
494 | global_settings.repeat_mode == REPEAT_ALL) | 494 | global_settings.repeat_mode == REPEAT_ALL) |
495 | { | 495 | { |
496 | #if CONFIG_CODEC != SWCODEC | ||
497 | talk_buffer_steal(); /* will use the mp3 buffer */ | ||
498 | #endif | ||
499 | audio_play(0); | 496 | audio_play(0); |
500 | viewer.current_playing_track = -1; | 497 | viewer.current_playing_track = -1; |
501 | } | 498 | } |
diff --git a/apps/plugin.c b/apps/plugin.c index 50fbb37012..32b77ad287 100644 --- a/apps/plugin.c +++ b/apps/plugin.c | |||
@@ -979,14 +979,8 @@ void* plugin_get_buffer(size_t *buffer_size) | |||
979 | */ | 979 | */ |
980 | void* plugin_get_audio_buffer(size_t *buffer_size) | 980 | void* plugin_get_audio_buffer(size_t *buffer_size) |
981 | { | 981 | { |
982 | #if CONFIG_CODEC == SWCODEC | ||
983 | return audio_get_buffer(true, buffer_size); | ||
984 | #else | ||
985 | audio_stop(); | 982 | audio_stop(); |
986 | talk_buffer_steal(); /* we use the mp3 buffer, need to tell */ | 983 | return audio_get_buffer(true, buffer_size); |
987 | *buffer_size = audiobufend - audiobuf; | ||
988 | return audiobuf; | ||
989 | #endif | ||
990 | } | 984 | } |
991 | 985 | ||
992 | /* The plugin wants to stay resident after leaving its main function, e.g. | 986 | /* The plugin wants to stay resident after leaving its main function, e.g. |
diff --git a/apps/plugin.h b/apps/plugin.h index a53df90d67..e2a5771b5c 100644 --- a/apps/plugin.h +++ b/apps/plugin.h | |||
@@ -828,12 +828,14 @@ struct plugin_api { | |||
828 | #endif /* CONFIG_CODEC == SWCODEC */ | 828 | #endif /* CONFIG_CODEC == SWCODEC */ |
829 | bool (*get_metadata)(struct mp3entry* id3, int fd, const char* trackname); | 829 | bool (*get_metadata)(struct mp3entry* id3, int fd, const char* trackname); |
830 | bool (*mp3info)(struct mp3entry *entry, const char *filename); | 830 | bool (*mp3info)(struct mp3entry *entry, const char *filename); |
831 | int (*count_mp3_frames)(int fd, int startpos, int filesize, | 831 | int (*count_mp3_frames)(int fd, int startpos, int filesize, |
832 | void (*progressfunc)(int)); | 832 | void (*progressfunc)(int), |
833 | unsigned char* buf, size_t buflen); | ||
833 | int (*create_xing_header)(int fd, long startpos, long filesize, | 834 | int (*create_xing_header)(int fd, long startpos, long filesize, |
834 | unsigned char *buf, unsigned long num_frames, | 835 | unsigned char *buf, unsigned long num_frames, |
835 | unsigned long rec_time, unsigned long header_template, | 836 | unsigned long rec_time, unsigned long header_template, |
836 | void (*progressfunc)(int), bool generate_toc); | 837 | void (*progressfunc)(int), bool generate_toc, |
838 | unsigned char* tempbuf, size_t tempbuf_len); | ||
837 | unsigned long (*find_next_frame)(int fd, long *offset, | 839 | unsigned long (*find_next_frame)(int fd, long *offset, |
838 | long max_offset, unsigned long reference_header); | 840 | long max_offset, unsigned long reference_header); |
839 | 841 | ||
diff --git a/apps/plugins/vbrfix.c b/apps/plugins/vbrfix.c index 98ca15b6a8..af7b817002 100644 --- a/apps/plugins/vbrfix.c +++ b/apps/plugins/vbrfix.c | |||
@@ -157,14 +157,15 @@ static bool vbr_fix(const char *selected_file) | |||
157 | xingupdate(0); | 157 | xingupdate(0); |
158 | 158 | ||
159 | num_frames = rb->count_mp3_frames(fd, entry.first_frame_offset, | 159 | num_frames = rb->count_mp3_frames(fd, entry.first_frame_offset, |
160 | flen, xingupdate); | 160 | flen, xingupdate, audiobuf, audiobuflen); |
161 | 161 | ||
162 | if(num_frames) { | 162 | if(num_frames) { |
163 | /* Note: We don't need to pass a template header because it will be | 163 | /* Note: We don't need to pass a template header because it will be |
164 | taken from the mpeg stream */ | 164 | taken from the mpeg stream */ |
165 | framelen = rb->create_xing_header(fd, entry.first_frame_offset, | 165 | framelen = rb->create_xing_header(fd, entry.first_frame_offset, |
166 | flen, xingbuf, num_frames, 0, | 166 | flen, xingbuf, num_frames, 0, |
167 | 0, xingupdate, true); | 167 | 0, xingupdate, true, |
168 | audiobuf, audiobuflen); | ||
168 | 169 | ||
169 | /* Try to fit the Xing header first in the stream. Replace the existing | 170 | /* Try to fit the Xing header first in the stream. Replace the existing |
170 | VBR header if there is one, else see if there is room between the | 171 | VBR header if there is one, else see if there is room between the |
diff --git a/apps/recorder/pcm_record.c b/apps/recorder/pcm_record.c index 8a832e409c..407a7e5f49 100644 --- a/apps/recorder/pcm_record.c +++ b/apps/recorder/pcm_record.c | |||
@@ -1643,14 +1643,12 @@ void enc_set_parameters(struct enc_parameters *params) | |||
1643 | logf("fnq files:%ld", fnq_size / MAX_PATH); | 1643 | logf("fnq files:%ld", fnq_size / MAX_PATH); |
1644 | 1644 | ||
1645 | #if defined(DEBUG) | 1645 | #if defined(DEBUG) |
1646 | logf("ab :%08lX", (uintptr_t)audiobuf); | ||
1647 | logf("pcm:%08lX", (uintptr_t)pcm_buffer); | 1646 | logf("pcm:%08lX", (uintptr_t)pcm_buffer); |
1648 | logf("enc:%08lX", (uintptr_t)enc_buffer); | 1647 | logf("enc:%08lX", (uintptr_t)enc_buffer); |
1649 | logf("res:%08lX", (uintptr_t)params->reserve_buffer); | 1648 | logf("res:%08lX", (uintptr_t)params->reserve_buffer); |
1650 | logf("wip:%08lX", (uintptr_t)wrap_id_p); | 1649 | logf("wip:%08lX", (uintptr_t)wrap_id_p); |
1651 | logf("fnq:%08lX", (uintptr_t)fn_queue); | 1650 | logf("fnq:%08lX", (uintptr_t)fn_queue); |
1652 | logf("end:%08lX", (uintptr_t)fn_queue + fnq_size); | 1651 | logf("end:%08lX", (uintptr_t)fn_queue + fnq_size); |
1653 | logf("abe:%08lX", (uintptr_t)audiobufend); | ||
1654 | #endif | 1652 | #endif |
1655 | 1653 | ||
1656 | /* init all chunk headers and reset indexes */ | 1654 | /* init all chunk headers and reset indexes */ |
diff --git a/apps/tagcache.c b/apps/tagcache.c index 6aa7709c00..0a491c58b5 100644 --- a/apps/tagcache.c +++ b/apps/tagcache.c | |||
@@ -107,7 +107,7 @@ static char curpath[TAG_MAXLEN+32]; | |||
107 | /* Used when removing duplicates. */ | 107 | /* Used when removing duplicates. */ |
108 | static char *tempbuf; /* Allocated when needed. */ | 108 | static char *tempbuf; /* Allocated when needed. */ |
109 | static long tempbufidx; /* Current location in buffer. */ | 109 | static long tempbufidx; /* Current location in buffer. */ |
110 | static long tempbuf_size; /* Buffer size (TEMPBUF_SIZE). */ | 110 | static size_t tempbuf_size; /* Buffer size (TEMPBUF_SIZE). */ |
111 | static long tempbuf_left; /* Buffer space left. */ | 111 | static long tempbuf_left; /* Buffer space left. */ |
112 | static long tempbuf_pos; | 112 | static long tempbuf_pos; |
113 | 113 | ||
@@ -3089,9 +3089,7 @@ static void allocate_tempbuf(void) | |||
3089 | tempbuf_size = 32*1024*1024; | 3089 | tempbuf_size = 32*1024*1024; |
3090 | tempbuf = malloc(tempbuf_size); | 3090 | tempbuf = malloc(tempbuf_size); |
3091 | #else | 3091 | #else |
3092 | tempbuf = (char *)(((long)audiobuf & ~0x03) + 0x04); | 3092 | buffer_get_buffer(&tempbuf_size); |
3093 | tempbuf_size = (long)audiobufend - (long)audiobuf - 4; | ||
3094 | audiobuf += tempbuf_size; | ||
3095 | #endif | 3093 | #endif |
3096 | } | 3094 | } |
3097 | 3095 | ||
@@ -3103,7 +3101,7 @@ static void free_tempbuf(void) | |||
3103 | #ifdef __PCTOOL__ | 3101 | #ifdef __PCTOOL__ |
3104 | free(tempbuf); | 3102 | free(tempbuf); |
3105 | #else | 3103 | #else |
3106 | audiobuf -= tempbuf_size; | 3104 | buffer_release_buffer(0); |
3107 | #endif | 3105 | #endif |
3108 | tempbuf = NULL; | 3106 | tempbuf = NULL; |
3109 | tempbuf_size = 0; | 3107 | tempbuf_size = 0; |
diff --git a/apps/talk.c b/apps/talk.c index 8c0f1f3a07..9fd6fb06ec 100644 --- a/apps/talk.c +++ b/apps/talk.c | |||
@@ -49,7 +49,7 @@ | |||
49 | 49 | ||
50 | MASCODEC | MASCODEC | SWCODEC | 50 | MASCODEC | MASCODEC | SWCODEC |
51 | (playing) | (stopped) | | 51 | (playing) | (stopped) | |
52 | audiobuf-----------+-----------+------------ | 52 | voicebuf-----------+-----------+------------ |
53 | audio | voice | thumbnail | 53 | audio | voice | thumbnail |
54 | |-----------|------------ | 54 | |-----------|------------ |
55 | | thumbnail | voice | 55 | | thumbnail | voice |
@@ -57,7 +57,7 @@ | |||
57 | | | filebuf | 57 | | | filebuf |
58 | | |------------ | 58 | | |------------ |
59 | | | audio | 59 | | | audio |
60 | audiobufend----------+-----------+------------ | 60 | voicebufend----------+-----------+------------ |
61 | 61 | ||
62 | SWCODEC allocates dedicated buffers, MASCODEC reuses audiobuf. */ | 62 | SWCODEC allocates dedicated buffers, MASCODEC reuses audiobuf. */ |
63 | 63 | ||
@@ -128,6 +128,7 @@ static uint8_t clip_age[QUEUE_SIZE]; | |||
128 | #endif | 128 | #endif |
129 | #endif | 129 | #endif |
130 | 130 | ||
131 | static char* voicebuf; /* root pointer to our buffer */ | ||
131 | static unsigned char* p_thumbnail = NULL; /* buffer for thumbnails */ | 132 | static unsigned char* p_thumbnail = NULL; /* buffer for thumbnails */ |
132 | /* Multiple thumbnails can be loaded back-to-back in this buffer. */ | 133 | /* Multiple thumbnails can be loaded back-to-back in this buffer. */ |
133 | static volatile int thumbnail_buf_used SHAREDBSS_ATTR; /* length of data in | 134 | static volatile int thumbnail_buf_used SHAREDBSS_ATTR; /* length of data in |
@@ -281,12 +282,18 @@ static unsigned char* get_clip(long id, long* p_size) | |||
281 | 282 | ||
282 | 283 | ||
283 | /* load the voice file into the mp3 buffer */ | 284 | /* load the voice file into the mp3 buffer */ |
284 | static void load_voicefile(bool probe) | 285 | static void load_voicefile(bool probe, char* buf, size_t bufsize) |
285 | { | 286 | { |
286 | int load_size; | 287 | union voicebuf { |
288 | unsigned char* buf; | ||
289 | struct voicefile* file; | ||
290 | }; | ||
291 | union voicebuf voicebuf; | ||
292 | |||
293 | int load_size, alloc_size; | ||
287 | int got_size; | 294 | int got_size; |
288 | #ifndef TALK_PARTIAL_LOAD | 295 | #ifndef TALK_PARTIAL_LOAD |
289 | int file_size; | 296 | size_t file_size; |
290 | #endif | 297 | #endif |
291 | #ifdef ROCKBOX_LITTLE_ENDIAN | 298 | #ifdef ROCKBOX_LITTLE_ENDIAN |
292 | int i; | 299 | int i; |
@@ -297,37 +304,43 @@ static void load_voicefile(bool probe) | |||
297 | if (filehandle < 0) /* failed to open */ | 304 | if (filehandle < 0) /* failed to open */ |
298 | goto load_err; | 305 | goto load_err; |
299 | 306 | ||
307 | voicebuf.buf = buf; | ||
308 | if (!voicebuf.buf) | ||
309 | goto load_err; | ||
310 | |||
300 | #ifndef TALK_PARTIAL_LOAD | 311 | #ifndef TALK_PARTIAL_LOAD |
301 | file_size = filesize(filehandle); | 312 | file_size = filesize(filehandle); |
302 | if (file_size > audiobufend - audiobuf) /* won't fit? */ | 313 | if (file_size > bufsize) /* won't fit? */ |
303 | goto load_err; | 314 | goto load_err; |
304 | #endif | 315 | #endif |
305 | 316 | ||
306 | #if defined(TALK_PROGRESSIVE_LOAD) || defined(TALK_PARTIAL_LOAD) | 317 | #if defined(TALK_PROGRESSIVE_LOAD) || defined(TALK_PARTIAL_LOAD) |
307 | /* load only the header for now */ | 318 | /* load only the header for now */ |
308 | load_size = offsetof(struct voicefile, index); | 319 | load_size = sizeof(struct voicefile); |
309 | #else /* load the full file */ | 320 | #else /* load the full file */ |
310 | load_size = file_size; | 321 | load_size = file_size; |
311 | #endif | 322 | #endif |
312 | 323 | ||
313 | #ifdef TALK_PARTIAL_LOAD | 324 | #ifdef TALK_PARTIAL_LOAD |
314 | if (load_size > audiobufend - audiobuf) /* won't fit? */ | 325 | if (load_size > bufsize) /* won't fit? */ |
315 | goto load_err; | 326 | goto load_err; |
316 | #endif | 327 | #endif |
317 | 328 | ||
318 | got_size = read(filehandle, audiobuf, load_size); | 329 | got_size = read(filehandle, voicebuf.buf, load_size); |
319 | if (got_size != load_size /* failure */) | 330 | if (got_size != load_size /* failure */) |
320 | goto load_err; | 331 | goto load_err; |
321 | 332 | ||
333 | alloc_size = load_size; | ||
334 | |||
322 | #ifdef ROCKBOX_LITTLE_ENDIAN | 335 | #ifdef ROCKBOX_LITTLE_ENDIAN |
323 | logf("Byte swapping voice file"); | 336 | logf("Byte swapping voice file"); |
324 | structec_convert(audiobuf, "lllll", 1, true); | 337 | structec_convert(voicebuf.buf, "lllll", 1, true); |
325 | #endif | 338 | #endif |
326 | 339 | ||
327 | if (((struct voicefile*)audiobuf)->table /* format check */ | 340 | /* format check */ |
328 | == offsetof(struct voicefile, index)) | 341 | if (voicebuf.file->table == sizeof(struct voicefile)) |
329 | { | 342 | { |
330 | p_voicefile = (struct voicefile*)audiobuf; | 343 | p_voicefile = voicebuf.file; |
331 | 344 | ||
332 | if (p_voicefile->version != VOICE_VERSION || | 345 | if (p_voicefile->version != VOICE_VERSION || |
333 | p_voicefile->target_id != TARGET_ID) | 346 | p_voicefile->target_id != TARGET_ID) |
@@ -337,9 +350,9 @@ static void load_voicefile(bool probe) | |||
337 | } | 350 | } |
338 | #if CONFIG_CODEC != SWCODEC | 351 | #if CONFIG_CODEC != SWCODEC |
339 | /* MASCODEC: now use audiobuf for voice then thumbnail */ | 352 | /* MASCODEC: now use audiobuf for voice then thumbnail */ |
340 | p_thumbnail = audiobuf + file_size; | 353 | p_thumbnail = voicebuf.buf + file_size; |
341 | p_thumbnail += (long)p_thumbnail % 2; /* 16-bit align */ | 354 | p_thumbnail += (long)p_thumbnail % 2; /* 16-bit align */ |
342 | size_for_thumbnail = audiobufend - p_thumbnail; | 355 | size_for_thumbnail = voicebuf.buf + bufsize - p_thumbnail; |
343 | #endif | 356 | #endif |
344 | } | 357 | } |
345 | else | 358 | else |
@@ -351,14 +364,15 @@ static void load_voicefile(bool probe) | |||
351 | * sizeof(struct clip_entry); | 364 | * sizeof(struct clip_entry); |
352 | 365 | ||
353 | #ifdef TALK_PARTIAL_LOAD | 366 | #ifdef TALK_PARTIAL_LOAD |
354 | if (load_size > audiobufend - audiobuf) /* won't fit? */ | 367 | if (load_size > bufsize) /* won't fit? */ |
355 | goto load_err; | 368 | goto load_err; |
356 | #endif | 369 | #endif |
357 | 370 | ||
358 | got_size = read(filehandle, | 371 | got_size = read(filehandle, &p_voicefile->index[0], load_size); |
359 | (unsigned char *) p_voicefile + offsetof(struct voicefile, index), load_size); | ||
360 | if (got_size != load_size) /* read error */ | 372 | if (got_size != load_size) /* read error */ |
361 | goto load_err; | 373 | goto load_err; |
374 | |||
375 | alloc_size += load_size; | ||
362 | #else | 376 | #else |
363 | close(filehandle); | 377 | close(filehandle); |
364 | filehandle = -1; | 378 | filehandle = -1; |
@@ -379,6 +393,11 @@ static void load_voicefile(bool probe) | |||
379 | p_silence = get_clip(VOICE_PAUSE, &silence_len); | 393 | p_silence = get_clip(VOICE_PAUSE, &silence_len); |
380 | } | 394 | } |
381 | 395 | ||
396 | #ifdef TALK_PARTIAL_LOAD | ||
397 | alloc_size += silence_len + QUEUE_SIZE; | ||
398 | #endif | ||
399 | if ((size_t)alloc_size > bufsize) | ||
400 | goto load_err; | ||
382 | return; | 401 | return; |
383 | 402 | ||
384 | load_err: | 403 | load_err: |
@@ -582,24 +601,31 @@ static void queue_clip(unsigned char* buf, long size, bool enqueue) | |||
582 | } | 601 | } |
583 | 602 | ||
584 | 603 | ||
585 | /* common code for talk_init() and talk_buffer_steal() */ | 604 | static void alloc_thumbnail_buf(void) |
586 | static void reset_state(void) | ||
587 | { | 605 | { |
588 | queue_write = queue_read = 0; /* reset the queue */ | ||
589 | p_voicefile = NULL; /* indicate no voicefile (trashed) */ | ||
590 | #if CONFIG_CODEC == SWCODEC | 606 | #if CONFIG_CODEC == SWCODEC |
591 | /* Allocate a dedicated thumbnail buffer - once */ | 607 | /* Allocate a dedicated thumbnail buffer - once */ |
592 | if (p_thumbnail == NULL) | 608 | if (p_thumbnail == NULL) |
593 | { | 609 | { |
594 | size_for_thumbnail = audiobufend - audiobuf; | 610 | size_for_thumbnail = buffer_available(); |
595 | if (size_for_thumbnail > MAX_THUMBNAIL_BUFSIZE) | 611 | if (size_for_thumbnail > MAX_THUMBNAIL_BUFSIZE) |
596 | size_for_thumbnail = MAX_THUMBNAIL_BUFSIZE; | 612 | size_for_thumbnail = MAX_THUMBNAIL_BUFSIZE; |
597 | p_thumbnail = buffer_alloc(size_for_thumbnail); | 613 | p_thumbnail = buffer_alloc(size_for_thumbnail); |
598 | } | 614 | } |
599 | #else | 615 | #else |
600 | /* Just use the audiobuf, without allocating anything */ | 616 | /* use the audio buffer now, need to release before loading a voice */ |
601 | p_thumbnail = audiobuf; | 617 | p_thumbnail = voicebuf; |
602 | size_for_thumbnail = audiobufend - audiobuf; | 618 | #endif |
619 | thumbnail_buf_used = 0; | ||
620 | } | ||
621 | |||
622 | /* common code for talk_init() and talk_buffer_steal() */ | ||
623 | static void reset_state(void) | ||
624 | { | ||
625 | queue_write = queue_read = 0; /* reset the queue */ | ||
626 | p_voicefile = NULL; /* indicate no voicefile (trashed) */ | ||
627 | #if CONFIG_CODEC != SWCODEC | ||
628 | p_thumbnail = NULL; /* don't leak buffer_alloc() for swcodec */ | ||
603 | #endif | 629 | #endif |
604 | 630 | ||
605 | #ifdef TALK_PARTIAL_LOAD | 631 | #ifdef TALK_PARTIAL_LOAD |
@@ -608,8 +634,8 @@ static void reset_state(void) | |||
608 | buffered_id[i] = -1; | 634 | buffered_id[i] = -1; |
609 | #endif | 635 | #endif |
610 | 636 | ||
611 | thumbnail_buf_used = 0; | ||
612 | p_silence = NULL; /* pause clip not accessible */ | 637 | p_silence = NULL; /* pause clip not accessible */ |
638 | voicebuf = NULL; | ||
613 | } | 639 | } |
614 | 640 | ||
615 | 641 | ||
@@ -655,12 +681,11 @@ void talk_init(void) | |||
655 | #endif | 681 | #endif |
656 | reset_state(); /* use this for most of our inits */ | 682 | reset_state(); /* use this for most of our inits */ |
657 | 683 | ||
658 | /* test if we can open and if it fits in the audiobuffer */ | ||
659 | size_t audiobufsz = audiobufend - audiobuf; | ||
660 | |||
661 | #ifdef TALK_PARTIAL_LOAD | 684 | #ifdef TALK_PARTIAL_LOAD |
685 | size_t bufsize; | ||
686 | char* buf = plugin_get_buffer(&bufsize); | ||
662 | /* we won't load the full file, we only need the index */ | 687 | /* we won't load the full file, we only need the index */ |
663 | load_voicefile(true); | 688 | load_voicefile(true, buf, bufsize); |
664 | if (!p_voicefile) | 689 | if (!p_voicefile) |
665 | return; | 690 | return; |
666 | 691 | ||
@@ -681,6 +706,9 @@ void talk_init(void) | |||
681 | p_voicefile = NULL; /* Don't pretend we can load talk clips just yet */ | 706 | p_voicefile = NULL; /* Don't pretend we can load talk clips just yet */ |
682 | #endif | 707 | #endif |
683 | 708 | ||
709 | |||
710 | /* test if we can open and if it fits in the audiobuffer */ | ||
711 | size_t audiobufsz = buffer_available(); | ||
684 | if (voicefile_size <= audiobufsz) { | 712 | if (voicefile_size <= audiobufsz) { |
685 | has_voicefile = true; | 713 | has_voicefile = true; |
686 | } else { | 714 | } else { |
@@ -688,6 +716,7 @@ void talk_init(void) | |||
688 | voicefile_size = 0; | 716 | voicefile_size = 0; |
689 | } | 717 | } |
690 | 718 | ||
719 | alloc_thumbnail_buf(); | ||
691 | close(filehandle); /* close again, this was just to detect presence */ | 720 | close(filehandle); /* close again, this was just to detect presence */ |
692 | filehandle = -1; | 721 | filehandle = -1; |
693 | } | 722 | } |
@@ -703,8 +732,22 @@ bool talk_voice_required(void) | |||
703 | #endif | 732 | #endif |
704 | 733 | ||
705 | /* return size of voice file */ | 734 | /* return size of voice file */ |
706 | int talk_get_bufsize(void) | 735 | int talk_get_buffer(void) |
736 | { | ||
737 | return voicefile_size; | ||
738 | } | ||
739 | |||
740 | /* Sets the buffer for the voicefile and returns how many bytes of this | ||
741 | * buffer we will use for the voicefile */ | ||
742 | size_t talkbuf_init(char *bufstart) | ||
707 | { | 743 | { |
744 | bool changed = voicebuf != bufstart; | ||
745 | |||
746 | if (bufstart) | ||
747 | voicebuf = bufstart; | ||
748 | if (changed) /* must reload voice file */ | ||
749 | reset_state(); | ||
750 | |||
708 | return voicefile_size; | 751 | return voicefile_size; |
709 | } | 752 | } |
710 | 753 | ||
@@ -741,7 +784,7 @@ int talk_id(int32_t id, bool enqueue) | |||
741 | #endif | 784 | #endif |
742 | 785 | ||
743 | if (p_voicefile == NULL && has_voicefile) | 786 | if (p_voicefile == NULL && has_voicefile) |
744 | load_voicefile(false); /* reload needed */ | 787 | load_voicefile(false, voicebuf, voicefile_size); /* reload needed */ |
745 | 788 | ||
746 | if (p_voicefile == NULL) /* still no voices? */ | 789 | if (p_voicefile == NULL) /* still no voices? */ |
747 | return -1; | 790 | return -1; |
@@ -819,7 +862,7 @@ static int _talk_file(const char* filename, | |||
819 | #endif | 862 | #endif |
820 | 863 | ||
821 | if (p_thumbnail == NULL || size_for_thumbnail <= 0) | 864 | if (p_thumbnail == NULL || size_for_thumbnail <= 0) |
822 | return -1; | 865 | alloc_thumbnail_buf(); |
823 | 866 | ||
824 | #if CONFIG_CODEC != SWCODEC | 867 | #if CONFIG_CODEC != SWCODEC |
825 | if(mp3info(&info, filename)) /* use this to find real start */ | 868 | if(mp3info(&info, filename)) /* use this to find real start */ |
diff --git a/apps/talk.h b/apps/talk.h index a2a9f44e4e..e1702147c7 100644 --- a/apps/talk.h +++ b/apps/talk.h | |||
@@ -80,6 +80,7 @@ void talk_init(void); | |||
80 | bool talk_voice_required(void); /* returns true if voice codec required */ | 80 | bool talk_voice_required(void); /* returns true if voice codec required */ |
81 | #endif | 81 | #endif |
82 | int talk_get_bufsize(void); /* get the loaded voice file size */ | 82 | int talk_get_bufsize(void); /* get the loaded voice file size */ |
83 | size_t talkbuf_init(char* bufstart); | ||
83 | void talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */ | 84 | void talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */ |
84 | bool is_voice_queued(void); /* Are there more voice clips to be spoken? */ | 85 | bool is_voice_queued(void); /* Are there more voice clips to be spoken? */ |
85 | int talk_id(int32_t id, bool enqueue); /* play a voice ID from voicefont */ | 86 | int talk_id(int32_t id, bool enqueue); /* play a voice ID from voicefont */ |