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) /* firmware file */ case FILE_ATTR_MOD: splash(0, ID2P(LANG_WAIT)); + audio_hard_stop(); rolo_load(buf); break; #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) static void init(void) { system_init(); + buffer_init(); kernel_init(); #ifdef APPLICATION paths_init(); #endif - buffer_init(); enable_irq(); lcd_init(); #ifdef HAVE_REMOTE_LCD @@ -428,13 +428,7 @@ static void init(void) #endif system_init(); -#if defined(IPOD_VIDEO) - audiobufend=(unsigned char *)audiobufend_lds; - if(MEMORYSIZE==64 && probed_ramsize!=64) - { - audiobufend -= (32<<20); - } -#endif + buffer_init(); kernel_init(); #ifdef HAVE_ADJUSTABLE_CPU_FREQ @@ -445,7 +439,6 @@ static void init(void) cpu_boost(true); #endif - buffer_init(); settings_reset(); 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, case INFO_BUFFER: /* buffer */ { - long kib = (audiobufend - audiobuf) / 1024; /* to KiB */ + long kib = buffer_available() / 1024; /* to KiB */ output_dyn_value(s1, sizeof(s1), kib, kbyte_units, true); snprintf(buffer, buffer_len, "%s %s", str(LANG_BUFFER_STAT), s1); } @@ -272,7 +272,7 @@ static int info_speak_item(int selected_item, void * data) case INFO_BUFFER: /* buffer */ { talk_id(LANG_BUFFER_STAT, false); - long kib = (audiobufend - audiobuf) / 1024; /* to KiB */ + long kib = buffer_available() / 1024; /* to KiB */ output_dyn_value(NULL, 0, kib, kbyte_units, true); break; } 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) static const struct text_message message={ lines, 2 }; button_clear_queue(); /* Empty the keyboard buffer */ if(gui_syncyesno_run(&message, NULL, NULL) == YESNO_YES) + { + audio_hard_stop(); rolo_load(BOOTDIR "/" BOOTFILE); + } } } 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, #ifndef __PCTOOL__ static int fnf_read_index; static int fnf_buf_len; +static unsigned char *fnf_buf; static int buf_getbyte(int fd, unsigned char *c) { if(fnf_read_index < fnf_buf_len) { - *c = audiobuf[fnf_read_index++]; + *c = fnf_buf[fnf_read_index++]; return 1; } else { - fnf_buf_len = read(fd, audiobuf, audiobufend - audiobuf); + fnf_buf_len = read(fd, fnf_buf, fnf_buf_len); if(fnf_buf_len < 0) return -1; @@ -329,7 +330,7 @@ static int buf_getbyte(int fd, unsigned char *c) if(fnf_buf_len > 0) { - *c = audiobuf[fnf_read_index++]; + *c = fnf_buf[fnf_read_index++]; return 1; } else @@ -345,7 +346,7 @@ static int buf_seek(int fd, int len) { len = fnf_read_index - fnf_buf_len; - fnf_buf_len = read(fd, audiobuf, audiobufend - audiobuf); + fnf_buf_len = read(fd, fnf_buf, fnf_buf_len); if(fnf_buf_len < 0) return -1; @@ -361,9 +362,10 @@ static int buf_seek(int fd, int len) return 0; } -static void buf_init(void) +static void buf_init(unsigned char* buf, size_t buflen) { - fnf_buf_len = 0; + fnf_buf = buf; + fnf_buf_len = buflen; fnf_read_index = 0; } @@ -372,8 +374,9 @@ static unsigned long buf_find_next_frame(int fd, long *offset, long max_offset) return __find_next_frame(fd, offset, max_offset, 0, buf_getbyte, true); } -static int audiobuflen; -static int mem_pos; +static size_t mem_buflen; +static unsigned char* mem_buf; +static size_t mem_pos; static int mem_cnt; static int mem_maxlen; @@ -381,8 +384,8 @@ static int mem_getbyte(int dummy, unsigned char *c) { dummy = dummy; - *c = audiobuf[mem_pos++]; - if(mem_pos >= audiobuflen) + *c = mem_buf[mem_pos++]; + if(mem_pos >= mem_buflen) mem_pos = 0; if(mem_cnt++ >= mem_maxlen) @@ -394,9 +397,11 @@ static int mem_getbyte(int dummy, unsigned char *c) unsigned long mem_find_next_frame(int startpos, long *offset, long max_offset, - unsigned long reference_header) + unsigned long reference_header, + unsigned char* buf, size_t buflen) { - audiobuflen = audiobufend - audiobuf; + mem_buf = buf; + mem_buflen = buflen; mem_pos = startpos; mem_cnt = 0; mem_maxlen = max_offset; @@ -620,8 +625,9 @@ static void long2bytes(unsigned char *buf, long val) buf[3] = val & 0xff; } -int count_mp3_frames(int fd, int startpos, int filesize, - void (*progressfunc)(int)) +int count_mp3_frames(int fd, int startpos, int filesize, + void (*progressfunc)(int), + unsigned char* buf, size_t buflen) { unsigned long header = 0; struct mp3info info; @@ -637,7 +643,7 @@ int count_mp3_frames(int fd, int startpos, int filesize, if(lseek(fd, startpos, SEEK_SET) < 0) return -1; - buf_init(); + buf_init(buf, buflen); /* Find out the total number of frames */ num_frames = 0; @@ -687,7 +693,8 @@ static const char cooltext[] = "Rockbox - rocks your box"; int create_xing_header(int fd, long startpos, long filesize, unsigned char *buf, unsigned long num_frames, unsigned long rec_time, unsigned long header_template, - void (*progressfunc)(int), bool generate_toc) + void (*progressfunc)(int), bool generate_toc, + unsigned char *tempbuf, size_t tempbuflen ) { struct mp3info info; unsigned char toc[100]; @@ -705,7 +712,7 @@ int create_xing_header(int fd, long startpos, long filesize, if(generate_toc) { lseek(fd, startpos, SEEK_SET); - buf_init(); + buf_init(tempbuf, tempbuflen); /* Generate filepos table */ 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 @@ #define MPEG_VERSION2 1 #define MPEG_VERSION2_5 2 +#include /* size_t */ + struct mp3info { /* Standard MP3 frame header fields */ int version; @@ -63,23 +65,21 @@ unsigned long find_next_frame(int fd, unsigned long reference_header); unsigned long mem_find_next_frame(int startpos, long *offset, - long max_offset, - unsigned long reference_header); + long max_offset, + unsigned long reference_header, + unsigned char* buf, size_t buflen); int get_mp3file_info(int fd, struct mp3info *info); -int count_mp3_frames(int fd, - int startpos, - int filesize, - void (*progressfunc)(int)); -int create_xing_header(int fd, - long startpos, - long filesize, - unsigned char *buf, - unsigned long num_frames, - unsigned long rec_time, - unsigned long header_template, - void (*progressfunc)(int), - bool generate_toc); + +int count_mp3_frames(int fd, int startpos, int filesize, + void (*progressfunc)(int), + unsigned char* buf, size_t buflen); + +int create_xing_header(int fd, long startpos, long filesize, + unsigned char *buf, unsigned long num_frames, + unsigned long rec_time, unsigned long header_template, + void (*progressfunc)(int), bool generate_toc, + unsigned char *tempbuf, size_t tempbuflen ); extern unsigned long bytes2int(unsigned long b0, 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 @@ #include "mp3data.h" #include "buffer.h" #include "mp3_playback.h" +#include "talk.h" #include "sound.h" #include "bitswap.h" #include "appevents.h" @@ -144,19 +145,19 @@ static unsigned int mpeg_errno; static bool playing = false; /* We are playing an MP3 stream */ static bool is_playing = false; /* We are (attempting to) playing MP3 files */ static bool paused; /* playback is paused */ +static char* mpeg_audiobuf; /* the audio buffer */ +static long audiobuflen; /* length of the audio buffer */ #ifdef SIMULATOR static char mpeg_stack[DEFAULT_STACK_SIZE]; static struct mp3entry taginfo; - #else /* !SIMULATOR */ static struct event_queue mpeg_queue SHAREDBSS_ATTR; static long mpeg_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)]; -static int audiobuflen; static int audiobuf_write; static int audiobuf_swapwrite; -static int audiobuf_read; +static long audiobuf_read; static int mpeg_file; @@ -490,6 +491,18 @@ unsigned long mpeg_get_last_header(void) #endif /* !SIMULATOR */ } + +unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size) +{ + (void)talk_buf; /* always grab the voice buffer for now */ + + audio_hard_stop(); + if (buffer_size) /* special case for talk_init() */ + return buffer_get_buffer(buffer_size); + return NULL; +} + + #ifndef SIMULATOR /* Send callback events to notify about removing old tracks. */ static void generate_unbuffer_events(void) @@ -708,7 +721,7 @@ void rec_tick(void) xor_b(0x08, &PADRH); /* Set PR inactive */ - audiobuf[audiobuf_write++] = data; + mpeg_audiobuf[audiobuf_write++] = data; if (audiobuf_write >= audiobuflen) audiobuf_write = 0; @@ -825,7 +838,7 @@ static void transfer_end(unsigned char** ppbuf, size_t* psize) } *psize = last_dma_chunk_size & 0xffff; - *ppbuf = audiobuf + audiobuf_read; + *ppbuf = mpeg_audiobuf + audiobuf_read; track = get_trackdata(0); if(track) track->id3.offset += last_dma_chunk_size; @@ -1128,7 +1141,7 @@ static void start_playback_if_ready(void) playing = true; last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); - mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end); + mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end); dma_underrun = false; if (!paused) @@ -1173,7 +1186,7 @@ static bool swap_one_chunk(void) amount_to_swap = MIN(audiobuf_write - audiobuf_swapwrite, amount_to_swap); - bitswap(audiobuf + audiobuf_swapwrite, amount_to_swap); + bitswap(mpeg_audiobuf + audiobuf_swapwrite, amount_to_swap); audiobuf_swapwrite += amount_to_swap; if(audiobuf_swapwrite >= audiobuflen) @@ -1341,7 +1354,7 @@ static void mpeg_thread(void) track_change(); audiobuf_read = get_trackdata(0)->mempos; last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); - mp3_play_data(audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end); + mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end); dma_underrun = false; last_dma_tick = current_tick; @@ -1501,7 +1514,7 @@ static void mpeg_thread(void) /* resume will start at new position */ last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); - mp3_play_data(audiobuf + audiobuf_read, + mp3_play_data(mpeg_audiobuf + audiobuf_read, last_dma_chunk_size, transfer_end); dma_underrun = false; } @@ -1632,7 +1645,7 @@ static void mpeg_thread(void) { DEBUGF("R\n"); t1 = current_tick; - len = read(mpeg_file, audiobuf + audiobuf_write, + len = read(mpeg_file, mpeg_audiobuf + audiobuf_write, amount_to_read); if(len > 0) { @@ -1659,7 +1672,7 @@ static void mpeg_thread(void) if(tagptr >= audiobuflen) tagptr -= audiobuflen; - if(audiobuf[tagptr] != tag[i]) + if(mpeg_audiobuf[tagptr] != tag[i]) { taglen = 0; break; @@ -1773,19 +1786,20 @@ static void mpeg_thread(void) startpos = prerecord_buffer[startpos].mempos; DEBUGF("Start looking at address %x (%x)\n", - audiobuf+startpos, startpos); + mpeg_audiobuf+startpos, startpos); saved_header = mpeg_get_last_header(); mem_find_next_frame(startpos, &offset, 1800, - saved_header); + saved_header, mpeg_audiobuf, + audiobuflen); audiobuf_read = startpos + offset; if(audiobuf_read >= audiobuflen) audiobuf_read -= audiobuflen; DEBUGF("New audiobuf_read address: %x (%x)\n", - audiobuf+audiobuf_read, audiobuf_read); + mpeg_audiobuf+audiobuf_read, audiobuf_read); level = disable_irq_save(); num_rec_bytes = get_unsaved_space(); @@ -1894,7 +1908,8 @@ static void mpeg_thread(void) save_endpos += audiobuflen; rc = mem_find_next_frame(save_endpos, &offset, 1800, - saved_header); + saved_header, mpeg_audiobuf, + audiobuflen); if (!rc) /* No header found, save whole buffer */ offset = 1800; @@ -1936,7 +1951,7 @@ static void mpeg_thread(void) #elif MEMORYSIZE == 8 amount_to_save = MIN(0x100000, amount_to_save); #endif - rc = write(mpeg_file, audiobuf + audiobuf_read, + rc = write(mpeg_file, mpeg_audiobuf + audiobuf_read, amount_to_save); if (rc < 0) { @@ -2256,21 +2271,21 @@ static void prepend_header(void) if(audiobuf_read < 0) { /* Clear the bottom half */ - memset(audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE); + memset(mpeg_audiobuf, 0, audiobuf_read + MPEG_RESERVED_HEADER_SPACE); /* And the top half */ audiobuf_read += audiobuflen; - memset(audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read); + memset(mpeg_audiobuf + audiobuf_read, 0, audiobuflen - audiobuf_read); } else { - memset(audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE); + memset(mpeg_audiobuf + audiobuf_read, 0, MPEG_RESERVED_HEADER_SPACE); } /* Copy the empty ID3 header */ startpos = audiobuf_read; for(i = 0; i < sizeof(empty_id3_header); i++) { - audiobuf[startpos++] = empty_id3_header[i]; + mpeg_audiobuf[startpos++] = empty_id3_header[i]; if(startpos == audiobuflen) startpos = 0; } @@ -2297,7 +2312,8 @@ static void update_header(void) /* saved_header is saved right before stopping the MAS */ framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer, frames, last_rec_time * (1000/HZ), - saved_header, NULL, false); + saved_header, NULL, false, + mpeg_audiobuf, audiobuflen); lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET); write(fd, xing_buffer, framelen); @@ -2645,8 +2661,22 @@ void audio_set_recording_options(struct audio_recording_options *options) #endif /* SIMULATOR */ #endif /* CONFIG_CODEC == MAS3587F */ +static void audio_reset_buffer(void) +{ + size_t bufsize; /* dont break strict-aliasing */ + talk_buffer_steal(); /* will use the mp3 buffer */ + + /* release buffer on behalf of any audio_get_buffer() caller, + * non-fatal if there was none */ + buffer_release_buffer(0); + /* re-aquire */ + mpeg_audiobuf = buffer_get_buffer(&bufsize); + audiobuflen = bufsize; +} + void audio_play(long offset) { + audio_reset_buffer(); #ifdef SIMULATOR char name_buf[MAX_PATH+1]; const char* trackname; @@ -2676,7 +2706,6 @@ void audio_play(long offset) } while(1); #else /* !SIMULATOR */ is_playing = true; - queue_post(&mpeg_queue, MPEG_PLAY, offset); #endif /* !SIMULATOR */ @@ -2700,6 +2729,8 @@ void audio_stop(void) is_playing = false; playing = false; #endif /* SIMULATOR */ + /* give voice our entire buffer */ + talkbuf_init(mpeg_audiobuf); } /* dummy */ @@ -2708,6 +2739,14 @@ void audio_stop_recording(void) audio_stop(); } +void audio_hard_stop(void) +{ + audio_stop(); + /* tell voice we obtain the buffer before freeing */ + talk_buffer_steal(); + buffer_release_buffer(0); +} + void audio_pause(void) { #ifndef SIMULATOR @@ -2864,8 +2903,12 @@ void audio_init(void) if (global_settings.cuesheet) curr_cuesheet = (struct cuesheet*)buffer_alloc(sizeof(struct cuesheet)); + size_t bufsize; /* don't break strict-aliasing */ + mpeg_audiobuf = buffer_get_buffer(&bufsize); + audiobuflen = bufsize; + /* give voice buffer until we start to play */ + talkbuf_init(mpeg_audiobuf); #ifndef SIMULATOR - audiobuflen = audiobufend - audiobuf; queue_init(&mpeg_queue, true); #endif /* !SIMULATOR */ 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) /* see audio_get_recording_buffer if this is modified */ logf("%s()", __func__); + /* release the buffer on behalf of any caller of audio_get_buffer() */ + buffer_release_buffer(0); + /* If the setup of anything allocated before the file buffer is changed, do check the adjustments after the buffer_alloc call as it will likely be affected and need sliding over */ /* Initially set up file buffer as all space available */ - unsigned char *filebuf = audiobuf + talk_get_bufsize(); - size_t filebuflen = audiobufend - filebuf; - size_t allocsize; + size_t filebuflen, allocsize; + unsigned char *filebuf = buffer_get_buffer(&filebuflen); - ALIGN_BUFFER(filebuf, filebuflen, sizeof (intptr_t)); + /* Subtract whatever voice needs */ + allocsize = talkbuf_init(filebuf); + allocsize = ALIGN_UP(allocsize, sizeof (intptr_t)); + if (allocsize > filebuflen) + goto bufpanic; + + filebuf += allocsize; + filebuflen -= allocsize; if (talk_voice_required()) { @@ -3335,6 +3344,7 @@ void audio_hard_stop(void) #ifdef PLAYBACK_VOICE voice_stop(); #endif + buffer_release_buffer(0); } /* Resume playback if paused */ @@ -3441,7 +3451,7 @@ void audio_flush_and_reload_tracks(void) voicing */ unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size) { - unsigned char *buf, *end; + unsigned char *buf; if (audio_is_initialized) { @@ -3461,7 +3471,7 @@ unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size) || !talk_voice_required()) { logf("get buffer: talk, audio"); - /* Ok to use everything from audiobuf to audiobufend - voice is loaded, + /* Ok to use everything from audiobuf - voice is loaded, the talk buffer is not needed because voice isn't being used, or could be AUDIOBUF_STATE_TRASHED already. If state is 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) talk_buffer_steal(); buffer_state = AUDIOBUF_STATE_TRASHED; } - - buf = audiobuf; - end = audiobufend; + buf = buffer_get_buffer(buffer_size); } else { @@ -3485,14 +3493,18 @@ unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size) /* Skip talk buffer and move pcm buffer to end to maximize available contiguous memory - no audio running means voice will not need the swap space */ + size_t siz, talkbuf_size; logf("get buffer: audio"); - buf = audiobuf + talk_get_bufsize(); - end = audiobufend - voicebuf_init(audiobufend); + /* call buffer_get_buffer() to make use of the locking mechanism */ + buf = buffer_get_buffer(&siz); + buf += talkbuf_size = talkbuf_init(buf); + siz -= talkbuf_size; + siz -= voicebuf_init(buf + siz); + *buffer_size = siz; + buffer_state = AUDIOBUF_STATE_VOICED_ONLY; } - *buffer_size = end - buf; - return buf; } @@ -3500,14 +3512,11 @@ unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size) /* Stop audio, voice and obtain all available buffer space */ unsigned char * audio_get_recording_buffer(size_t *buffer_size) { - audio_hard_stop(); talk_buffer_steal(); + audio_hard_stop(); - unsigned char *end = audiobufend; buffer_state = AUDIOBUF_STATE_TRASHED; - *buffer_size = end - audiobuf; - - return (unsigned char *)audiobuf; + return buffer_get_buffer(buffer_size); } #endif /* HAVE_RECORDING */ 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); long audio_filebufused(void); void audio_pre_ff_rewind(void); void audio_skip(int direction); -void audio_hard_stop(void); /* Stops audio from serving playback */ void audio_set_cuesheet(int enable); #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, { /* use mp3 buffer for maximum load speed */ audio_stop(); -#if CONFIG_CODEC != SWCODEC - talk_buffer_steal(); /* we use the mp3 buffer, need to tell */ - buflen = (audiobufend - audiobuf); - buffer = (char *)audiobuf; -#else - buffer = (char *)audio_get_buffer(false, &buflen); -#endif + buffer = audio_get_buffer(false, &buflen); } store_index = true; @@ -2018,13 +2012,7 @@ int playlist_resume(void) bool sorted = true; /* use mp3 buffer for maximum load speed */ -#if CONFIG_CODEC != SWCODEC - talk_buffer_steal(); /* we use the mp3 buffer, need to tell */ - buflen = (audiobufend - audiobuf); - buffer = (char *)audiobuf; -#else buffer = (char *)audio_get_buffer(false, &buflen); -#endif empty_playlist(playlist, true); @@ -2449,10 +2437,6 @@ void playlist_start(int start_index, int offset) playlist->index = start_index; -#if CONFIG_CODEC != SWCODEC - talk_buffer_steal(); /* will use the mp3 buffer */ -#endif - playlist->started = true; sync_control(playlist, false); 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) if (current_track->display_index!=viewer.num_tracks || global_settings.repeat_mode == REPEAT_ALL) { -#if CONFIG_CODEC != SWCODEC - talk_buffer_steal(); /* will use the mp3 buffer */ -#endif audio_play(0); viewer.current_playing_track = -1; } 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) */ void* plugin_get_audio_buffer(size_t *buffer_size) { -#if CONFIG_CODEC == SWCODEC - return audio_get_buffer(true, buffer_size); -#else audio_stop(); - talk_buffer_steal(); /* we use the mp3 buffer, need to tell */ - *buffer_size = audiobufend - audiobuf; - return audiobuf; -#endif + return audio_get_buffer(true, buffer_size); } /* 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 { #endif /* CONFIG_CODEC == SWCODEC */ bool (*get_metadata)(struct mp3entry* id3, int fd, const char* trackname); bool (*mp3info)(struct mp3entry *entry, const char *filename); - int (*count_mp3_frames)(int fd, int startpos, int filesize, - void (*progressfunc)(int)); + int (*count_mp3_frames)(int fd, int startpos, int filesize, + void (*progressfunc)(int), + unsigned char* buf, size_t buflen); int (*create_xing_header)(int fd, long startpos, long filesize, unsigned char *buf, unsigned long num_frames, unsigned long rec_time, unsigned long header_template, - void (*progressfunc)(int), bool generate_toc); + void (*progressfunc)(int), bool generate_toc, + unsigned char* tempbuf, size_t tempbuf_len); unsigned long (*find_next_frame)(int fd, long *offset, long max_offset, unsigned long reference_header); 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) xingupdate(0); num_frames = rb->count_mp3_frames(fd, entry.first_frame_offset, - flen, xingupdate); + flen, xingupdate, audiobuf, audiobuflen); if(num_frames) { /* Note: We don't need to pass a template header because it will be taken from the mpeg stream */ framelen = rb->create_xing_header(fd, entry.first_frame_offset, flen, xingbuf, num_frames, 0, - 0, xingupdate, true); + 0, xingupdate, true, + audiobuf, audiobuflen); /* Try to fit the Xing header first in the stream. Replace the existing 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) logf("fnq files:%ld", fnq_size / MAX_PATH); #if defined(DEBUG) - logf("ab :%08lX", (uintptr_t)audiobuf); logf("pcm:%08lX", (uintptr_t)pcm_buffer); logf("enc:%08lX", (uintptr_t)enc_buffer); logf("res:%08lX", (uintptr_t)params->reserve_buffer); logf("wip:%08lX", (uintptr_t)wrap_id_p); logf("fnq:%08lX", (uintptr_t)fn_queue); logf("end:%08lX", (uintptr_t)fn_queue + fnq_size); - logf("abe:%08lX", (uintptr_t)audiobufend); #endif /* 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]; /* Used when removing duplicates. */ static char *tempbuf; /* Allocated when needed. */ static long tempbufidx; /* Current location in buffer. */ -static long tempbuf_size; /* Buffer size (TEMPBUF_SIZE). */ +static size_t tempbuf_size; /* Buffer size (TEMPBUF_SIZE). */ static long tempbuf_left; /* Buffer space left. */ static long tempbuf_pos; @@ -3089,9 +3089,7 @@ static void allocate_tempbuf(void) tempbuf_size = 32*1024*1024; tempbuf = malloc(tempbuf_size); #else - tempbuf = (char *)(((long)audiobuf & ~0x03) + 0x04); - tempbuf_size = (long)audiobufend - (long)audiobuf - 4; - audiobuf += tempbuf_size; + buffer_get_buffer(&tempbuf_size); #endif } @@ -3103,7 +3101,7 @@ static void free_tempbuf(void) #ifdef __PCTOOL__ free(tempbuf); #else - audiobuf -= tempbuf_size; + buffer_release_buffer(0); #endif tempbuf = NULL; 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 @@ MASCODEC | MASCODEC | SWCODEC (playing) | (stopped) | - audiobuf-----------+-----------+------------ + voicebuf-----------+-----------+------------ audio | voice | thumbnail |-----------|------------ | thumbnail | voice @@ -57,7 +57,7 @@ | | filebuf | |------------ | | audio - audiobufend----------+-----------+------------ + voicebufend----------+-----------+------------ SWCODEC allocates dedicated buffers, MASCODEC reuses audiobuf. */ @@ -128,6 +128,7 @@ static uint8_t clip_age[QUEUE_SIZE]; #endif #endif +static char* voicebuf; /* root pointer to our buffer */ static unsigned char* p_thumbnail = NULL; /* buffer for thumbnails */ /* Multiple thumbnails can be loaded back-to-back in this buffer. */ 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) /* load the voice file into the mp3 buffer */ -static void load_voicefile(bool probe) +static void load_voicefile(bool probe, char* buf, size_t bufsize) { - int load_size; + union voicebuf { + unsigned char* buf; + struct voicefile* file; + }; + union voicebuf voicebuf; + + int load_size, alloc_size; int got_size; #ifndef TALK_PARTIAL_LOAD - int file_size; + size_t file_size; #endif #ifdef ROCKBOX_LITTLE_ENDIAN int i; @@ -297,37 +304,43 @@ static void load_voicefile(bool probe) if (filehandle < 0) /* failed to open */ goto load_err; + voicebuf.buf = buf; + if (!voicebuf.buf) + goto load_err; + #ifndef TALK_PARTIAL_LOAD file_size = filesize(filehandle); - if (file_size > audiobufend - audiobuf) /* won't fit? */ + if (file_size > bufsize) /* won't fit? */ goto load_err; #endif #if defined(TALK_PROGRESSIVE_LOAD) || defined(TALK_PARTIAL_LOAD) /* load only the header for now */ - load_size = offsetof(struct voicefile, index); + load_size = sizeof(struct voicefile); #else /* load the full file */ load_size = file_size; #endif #ifdef TALK_PARTIAL_LOAD - if (load_size > audiobufend - audiobuf) /* won't fit? */ + if (load_size > bufsize) /* won't fit? */ goto load_err; #endif - got_size = read(filehandle, audiobuf, load_size); + got_size = read(filehandle, voicebuf.buf, load_size); if (got_size != load_size /* failure */) goto load_err; + alloc_size = load_size; + #ifdef ROCKBOX_LITTLE_ENDIAN logf("Byte swapping voice file"); - structec_convert(audiobuf, "lllll", 1, true); + structec_convert(voicebuf.buf, "lllll", 1, true); #endif - if (((struct voicefile*)audiobuf)->table /* format check */ - == offsetof(struct voicefile, index)) + /* format check */ + if (voicebuf.file->table == sizeof(struct voicefile)) { - p_voicefile = (struct voicefile*)audiobuf; + p_voicefile = voicebuf.file; if (p_voicefile->version != VOICE_VERSION || p_voicefile->target_id != TARGET_ID) @@ -337,9 +350,9 @@ static void load_voicefile(bool probe) } #if CONFIG_CODEC != SWCODEC /* MASCODEC: now use audiobuf for voice then thumbnail */ - p_thumbnail = audiobuf + file_size; + p_thumbnail = voicebuf.buf + file_size; p_thumbnail += (long)p_thumbnail % 2; /* 16-bit align */ - size_for_thumbnail = audiobufend - p_thumbnail; + size_for_thumbnail = voicebuf.buf + bufsize - p_thumbnail; #endif } else @@ -351,14 +364,15 @@ static void load_voicefile(bool probe) * sizeof(struct clip_entry); #ifdef TALK_PARTIAL_LOAD - if (load_size > audiobufend - audiobuf) /* won't fit? */ + if (load_size > bufsize) /* won't fit? */ goto load_err; #endif - got_size = read(filehandle, - (unsigned char *) p_voicefile + offsetof(struct voicefile, index), load_size); + got_size = read(filehandle, &p_voicefile->index[0], load_size); if (got_size != load_size) /* read error */ goto load_err; + + alloc_size += load_size; #else close(filehandle); filehandle = -1; @@ -379,6 +393,11 @@ static void load_voicefile(bool probe) p_silence = get_clip(VOICE_PAUSE, &silence_len); } +#ifdef TALK_PARTIAL_LOAD + alloc_size += silence_len + QUEUE_SIZE; +#endif + if ((size_t)alloc_size > bufsize) + goto load_err; return; load_err: @@ -582,24 +601,31 @@ static void queue_clip(unsigned char* buf, long size, bool enqueue) } -/* common code for talk_init() and talk_buffer_steal() */ -static void reset_state(void) +static void alloc_thumbnail_buf(void) { - queue_write = queue_read = 0; /* reset the queue */ - p_voicefile = NULL; /* indicate no voicefile (trashed) */ #if CONFIG_CODEC == SWCODEC /* Allocate a dedicated thumbnail buffer - once */ if (p_thumbnail == NULL) { - size_for_thumbnail = audiobufend - audiobuf; + size_for_thumbnail = buffer_available(); if (size_for_thumbnail > MAX_THUMBNAIL_BUFSIZE) size_for_thumbnail = MAX_THUMBNAIL_BUFSIZE; p_thumbnail = buffer_alloc(size_for_thumbnail); } #else - /* Just use the audiobuf, without allocating anything */ - p_thumbnail = audiobuf; - size_for_thumbnail = audiobufend - audiobuf; + /* use the audio buffer now, need to release before loading a voice */ + p_thumbnail = voicebuf; +#endif + thumbnail_buf_used = 0; +} + +/* common code for talk_init() and talk_buffer_steal() */ +static void reset_state(void) +{ + queue_write = queue_read = 0; /* reset the queue */ + p_voicefile = NULL; /* indicate no voicefile (trashed) */ +#if CONFIG_CODEC != SWCODEC + p_thumbnail = NULL; /* don't leak buffer_alloc() for swcodec */ #endif #ifdef TALK_PARTIAL_LOAD @@ -608,8 +634,8 @@ static void reset_state(void) buffered_id[i] = -1; #endif - thumbnail_buf_used = 0; p_silence = NULL; /* pause clip not accessible */ + voicebuf = NULL; } @@ -655,12 +681,11 @@ void talk_init(void) #endif reset_state(); /* use this for most of our inits */ - /* test if we can open and if it fits in the audiobuffer */ - size_t audiobufsz = audiobufend - audiobuf; - #ifdef TALK_PARTIAL_LOAD + size_t bufsize; + char* buf = plugin_get_buffer(&bufsize); /* we won't load the full file, we only need the index */ - load_voicefile(true); + load_voicefile(true, buf, bufsize); if (!p_voicefile) return; @@ -681,6 +706,9 @@ void talk_init(void) p_voicefile = NULL; /* Don't pretend we can load talk clips just yet */ #endif + + /* test if we can open and if it fits in the audiobuffer */ + size_t audiobufsz = buffer_available(); if (voicefile_size <= audiobufsz) { has_voicefile = true; } else { @@ -688,6 +716,7 @@ void talk_init(void) voicefile_size = 0; } + alloc_thumbnail_buf(); close(filehandle); /* close again, this was just to detect presence */ filehandle = -1; } @@ -703,11 +732,25 @@ bool talk_voice_required(void) #endif /* return size of voice file */ -int talk_get_bufsize(void) +int talk_get_buffer(void) { return voicefile_size; } +/* Sets the buffer for the voicefile and returns how many bytes of this + * buffer we will use for the voicefile */ +size_t talkbuf_init(char *bufstart) +{ + bool changed = voicebuf != bufstart; + + if (bufstart) + voicebuf = bufstart; + if (changed) /* must reload voice file */ + reset_state(); + + return voicefile_size; +} + /* somebody else claims the mp3 buffer, e.g. for regular play/record */ void talk_buffer_steal(void) { @@ -741,7 +784,7 @@ int talk_id(int32_t id, bool enqueue) #endif if (p_voicefile == NULL && has_voicefile) - load_voicefile(false); /* reload needed */ + load_voicefile(false, voicebuf, voicefile_size); /* reload needed */ if (p_voicefile == NULL) /* still no voices? */ return -1; @@ -819,7 +862,7 @@ static int _talk_file(const char* filename, #endif if (p_thumbnail == NULL || size_for_thumbnail <= 0) - return -1; + alloc_thumbnail_buf(); #if CONFIG_CODEC != SWCODEC 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); bool talk_voice_required(void); /* returns true if voice codec required */ #endif int talk_get_bufsize(void); /* get the loaded voice file size */ +size_t talkbuf_init(char* bufstart); void talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */ bool is_voice_queued(void); /* Are there more voice clips to be spoken? */ int talk_id(int32_t id, bool enqueue); /* play a voice ID from voicefont */ diff --git a/firmware/buffer.c b/firmware/buffer.c index c317cec924..2168087bd9 100644 --- a/firmware/buffer.c +++ b/firmware/buffer.c @@ -19,19 +19,33 @@ * ****************************************************************************/ #include +#include +#include "system.h" #include "buffer.h" #include "panic.h" #include "logf.h" #if (CONFIG_PLATFORM & PLATFORM_HOSTED) -unsigned char audiobuffer[(MEMORYSIZE*1024-256)*1024]; -unsigned char *audiobufend = audiobuffer + sizeof(audiobuffer); #else -/* defined in linker script */ -extern unsigned char audiobuffer[]; #endif -unsigned char *audiobuf; +/* defined in linker script */ +#if (CONFIG_PLATFORM & PLATFORM_NATIVE) +#if defined(IPOD_VIDEO) +extern unsigned char *audiobufend_lds[]; +unsigned char *audiobufend; +#else /* !IPOD_VIDEO */ +extern unsigned char audiobufend[]; +#endif +/* defined in linker script */ +extern unsigned char audiobuffer[]; +#else /* PLATFORM_HOSTED */ +unsigned char audiobuffer[(MEMORYSIZE*1024-256)*1024]; +unsigned char *audiobufend = audiobuffer + sizeof(audiobuffer); +extern unsigned char *audiobufend; +#endif + +static unsigned char *audiobuf; #ifdef BUFFER_ALLOC_DEBUG static unsigned char *audiobuf_orig_start; @@ -54,13 +68,68 @@ void buffer_init(void) { /* 32-bit aligned */ audiobuf = (void *)(((unsigned long)audiobuffer + 3) & ~3); + +#if defined(IPOD_VIDEO) + audiobufend=(unsigned char *)audiobufend_lds; + if(MEMORYSIZE==64 && probed_ramsize!=64) + { + audiobufend -= (32<<20); + } +#endif + #ifdef BUFFER_ALLOC_DEBUG audiobuf_orig_start = audiobuf; #endif /* BUFFER_ALLOC_DEBUG */ } +/* protect concurrent access */ +static volatile int lock; + +/* + * Give the entire buffer, return the size in size. + * The caller needs to make sure audiobuf is not otherwise used + * + * Note that this does not modify the buffer position (buffer_release_buffer() + * does), so call this if you want to aquire temporary memory + **/ +#define _ALIGN (sizeof(char*)) +void *buffer_get_buffer(size_t *size) +{ + if (lock) + panicf("concurrent audiobuf access"); + lock = 1; + audiobuf = ALIGN_UP(audiobuf, sizeof(intptr_t)); + *size = (audiobufend - audiobuf); + return audiobuf; +} + +/* + * Release the buffer gotten with buffer_get_buffer + * + * size should have the amount of bytes (from the front) that caller keeps for + * its own, 0 if the entire buffer is to be released + * + * safe to be called with size=0 even if the buffer wasn't claimed before + **/ +void buffer_release_buffer(size_t size) +{ + audiobuf += size; + /* ensure alignment */ + audiobuf = ALIGN_UP(audiobuf, sizeof(intptr_t)); + lock = 0; +} + +/* + * Query how much free space the buffer has */ +size_t buffer_available(void) +{ + return audiobufend - audiobuf; +} + void *buffer_alloc(size_t size) { + if (lock) /* it's not save to call this here */ + panicf("buffer_alloc(): exclusive buffer owner"); void *retval; #ifdef BUFFER_ALLOC_DEBUG struct buffer_start_marker *start; diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index 08fe5098f5..d114a6ac62 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c @@ -862,22 +862,26 @@ int dircache_build(int last_size) * and their corresponding d_name from the end * after generation the buffer will be compacted with DIRCACHE_RESERVE * free bytes inbetween */ - audiobuf = ALIGN_UP(audiobuf, sizeof(struct dircache_entry)); - dircache_root = (struct dircache_entry*)audiobuf; - d_names_start = d_names_end = audiobufend - 1; + size_t got_size; + char* buf = buffer_get_buffer(&got_size); + ALIGN_BUFFER(buf, got_size, sizeof(struct dircache_entry)); + d_names_start = d_names_end = (char*)dircache_root + got_size - 1; dircache_size = 0; generate_dot_d_names(); /* Start a non-transparent rebuild. */ int res = dircache_do_rebuild(); if (res < 0) - return res; + goto fail; /* now compact the dircache buffer */ char* dst = ((char*)&dircache_root[entry_count] + DIRCACHE_RESERVE); ptrdiff_t offset = d_names_start - dst; if (offset <= 0) /* something went wrong */ - return -1; + { + res = -1; + goto fail; + } /* memmove d_names down, there's a possibility of overlap * equivaent to dircache_size - entry_count*sizeof(struct dircache_entry) */ @@ -896,15 +900,19 @@ int dircache_build(int last_size) /* equivalent to dircache_size + DIRCACHE_RESERVE */ allocated_size = (d_names_end - (char*)dircache_root); reserve_used = 0; - audiobuf += allocated_size; + buffer_release_buffer(allocated_size); + return res; +fail: + dircache_disable(); + buffer_release_buffer(0); return res; } /** * Steal the allocated dircache buffer and disable dircache. */ -void* dircache_steal_buffer(long *size) +void* dircache_steal_buffer(size_t *size) { dircache_disable(); if (dircache_size == 0) diff --git a/firmware/export/audio.h b/firmware/export/audio.h index 910791c7fd..6757bf143b 100644 --- a/firmware/export/audio.h +++ b/firmware/export/audio.h @@ -51,6 +51,8 @@ void audio_init(void) INIT_ATTR; void audio_play(long offset); void audio_stop(void); +/* Stops audio from serving playback and frees resources*/ +void audio_hard_stop(void); void audio_pause(void); void audio_resume(void); void audio_next(void); @@ -68,11 +70,11 @@ void audio_error_clear(void); int audio_get_file_pos(void); void audio_beep(int duration); -#if CONFIG_CODEC == SWCODEC /* Required call when audio buffer is required for some other purpose */ +/* implemented in apps but called from firmware(!) */ unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size); -/* only implemented in playback.c, but called from firmware */ +#if CONFIG_CODEC == SWCODEC void audio_next_dir(void); void audio_prev_dir(void); diff --git a/firmware/include/buffer.h b/firmware/include/buffer.h index 18f53f0000..bdf91bcb3f 100644 --- a/firmware/include/buffer.h +++ b/firmware/include/buffer.h @@ -22,21 +22,13 @@ #define BUFFER_H #include "config.h" -/* defined in linker script */ -#if (CONFIG_PLATFORM & PLATFORM_NATIVE) -#if defined(IPOD_VIDEO) -extern unsigned char *audiobufend_lds[]; -unsigned char *audiobufend; -#else -extern unsigned char audiobufend[]; -#endif -#else -extern unsigned char *audiobufend; -#endif - -extern unsigned char *audiobuf; void buffer_init(void) INIT_ATTR; + +void* buffer_get_buffer(size_t *size); +void buffer_release_buffer(size_t size); +size_t buffer_available(void); + void *buffer_alloc(size_t size); #ifdef BUFFER_ALLOC_DEBUG diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h index 0ac937df84..6beeeb6c23 100644 --- a/firmware/include/dircache.h +++ b/firmware/include/dircache.h @@ -23,6 +23,7 @@ #include "config.h" #include "dir_uncached.h" +#include /* size_t */ #ifdef HAVE_DIRCACHE @@ -65,7 +66,7 @@ void dircache_init(void) INIT_ATTR; int dircache_load(void); int dircache_save(void); int dircache_build(int last_size); -void* dircache_steal_buffer(long *size); +void* dircache_steal_buffer(size_t *size); bool dircache_is_enabled(void); bool dircache_is_initializing(void); void dircache_set_appflag(long mask); diff --git a/firmware/rolo.c b/firmware/rolo.c index 078a4e9827..9b6f4fec4a 100644 --- a/firmware/rolo.c +++ b/firmware/rolo.c @@ -99,6 +99,7 @@ void rolo_restart_cop(void) static void rolo_error(const char *text) { + buffer_release_buffer(0); lcd_clear_display(); lcd_puts(0, 0, "ROLO error:"); lcd_puts_scroll(0, 1, text); @@ -213,6 +214,8 @@ int rolo_load(const char* filename) unsigned short checksum,file_checksum; #endif unsigned char* ramstart = (void*)&loadaddress; + unsigned char* filebuf; + size_t filebuf_size; lcd_clear_display(); lcd_puts(0, 0, "ROLO..."); @@ -235,6 +238,10 @@ int rolo_load(const char* filename) length = filesize(fd) - FIRMWARE_OFFSET_FILE_DATA; + /* get the system buffer. release only in case of error, otherwise + * we don't return anyway */ + filebuf = buffer_get_buffer(&filebuf_size); + #if CONFIG_CPU != SH7034 /* Read and save checksum */ lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET); @@ -260,7 +267,14 @@ int rolo_load(const char* filename) lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET); - if (read(fd, audiobuf, length) != length) { + /* this shouldn't happen, but well */ + if ((long)filebuf_size < length) + { + rolo_error("File too big"); + return -1; + } + + if (read(fd, filebuf, length) != length) { rolo_error("Error Reading File"); return -1; } @@ -268,12 +282,12 @@ int rolo_load(const char* filename) #ifdef MI4_FORMAT /* Check CRC32 to see if we have a valid file */ chksum_crc32gentab(); - checksum = chksum_crc32 (audiobuf, length); + checksum = chksum_crc32 (filebuf, length); #else checksum = MODEL_NUMBER; for(i = 0;i < length;i++) { - checksum += audiobuf[i]; + checksum += filebuf[i]; } #endif @@ -329,12 +343,12 @@ int rolo_load(const char* filename) lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET); /* verify that file can be read and descrambled */ - if ((audiobuf + (2*length)+4) >= audiobufend) { + if ((size_t)((2*length)+4) >= filebuf_size) { rolo_error("Not enough room to load file"); return -1; } - if (read(fd, &audiobuf[length], length) != (int)length) { + if (read(fd, &filebuf[length], length) != (int)length) { rolo_error("Error Reading File"); return -1; } @@ -342,7 +356,7 @@ int rolo_load(const char* filename) lcd_puts(0, 1, "Descramble"); lcd_update(); - checksum = descramble(audiobuf + length, audiobuf, length); + checksum = descramble(filebuf + length, filebuf, length); /* Verify checksum against file header */ if (checksum != file_checksum) { @@ -374,7 +388,7 @@ int rolo_load(const char* filename) PAIOR = 0x0FA0; #endif #endif - rolo_restart(audiobuf, ramstart, length); + rolo_restart(filebuf, ramstart, length); return 0; /* this is never reached */ (void)checksum; (void)file_checksum;