GSoC/Buflib: Replace all direct accesses to audiobuf with buffer API functions.
Namely, introduce buffer_get_buffer() and buffer_release_buffer().
buffer_get_buffer() aquires all available and grabs a lock, attempting to
call buffer_alloc() or buffer_get_buffer() while this lock is locked will cause
a panicf() (doesn't actually happen, but is for debugging purpose).
buffer_release_buffer() unlocks that lock and can additionally increment the
audiobuf buffer to make an allocation. Pass 0 to only unlock if buffer was
used temporarily only.
buffer_available() is a replacement function to query audiobuflen, i.e. what's
left in the buffer.
Buffer init is moved up in the init chain and handles ipodvideo64mb internally.
Further changes happened to mp3data.c and talk.c as to not call the above API
functions, but get the buffer from callers. The caller is the audio system
which has the buffer lock while mp3data.c and talk mess with the buffer.
mpeg.c now implements some buffer related functions of playback.h, especially
audio_get_buffer(), allowing to reduce #ifdef hell a tiny bit.
audiobuf and audiobufend are local to buffer.c now.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30308 a1c6a512-1295-4272-9138-f99709370657
diff --git a/apps/filetree.c b/apps/filetree.c
index a7c989f..1aee80b 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -600,6 +600,7 @@
/* 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 0b566b5..9cb7245 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -337,11 +337,11 @@
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 @@
#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 @@
cpu_boost(true);
#endif
- buffer_init();
settings_reset();
diff --git a/apps/menus/main_menu.c b/apps/menus/main_menu.c
index 6ee7ba4..c5758d1 100644
--- a/apps/menus/main_menu.c
+++ b/apps/menus/main_menu.c
@@ -182,7 +182,7 @@
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 @@
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 fef55d5..d74fe73 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -766,7 +766,10 @@
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 9fed727..53f13f4 100644
--- a/apps/mp3data.c
+++ b/apps/mp3data.c
@@ -311,17 +311,18 @@
#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 @@
if(fnf_buf_len > 0)
{
- *c = audiobuf[fnf_read_index++];
+ *c = fnf_buf[fnf_read_index++];
return 1;
}
else
@@ -345,7 +346,7 @@
{
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 @@
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 @@
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 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
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 edda352..762c2f4 100644
--- a/apps/mp3data.h
+++ b/apps/mp3data.h
@@ -26,6 +26,8 @@
#define MPEG_VERSION2 1
#define MPEG_VERSION2_5 2
+#include <string.h> /* size_t */
+
struct mp3info {
/* Standard MP3 frame header fields */
int version;
@@ -63,23 +65,21 @@
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 b11445f..a0182ad 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 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 @@
#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 @@
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 @@
}
*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 @@
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 @@
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 @@
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 @@
/* 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 @@
{
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 @@
if(tagptr >= audiobuflen)
tagptr -= audiobuflen;
- if(audiobuf[tagptr] != tag[i])
+ if(mpeg_audiobuf[tagptr] != tag[i])
{
taglen = 0;
break;
@@ -1773,19 +1786,20 @@
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 @@
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 @@
#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 @@
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 @@
/* 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 @@
#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 @@
} while(1);
#else /* !SIMULATOR */
is_playing = true;
-
queue_post(&mpeg_queue, MPEG_PLAY, offset);
#endif /* !SIMULATOR */
@@ -2700,6 +2729,8 @@
is_playing = false;
playing = false;
#endif /* SIMULATOR */
+ /* give voice our entire buffer */
+ talkbuf_init(mpeg_audiobuf);
}
/* dummy */
@@ -2708,6 +2739,14 @@
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 @@
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 fe9bd57..3f6ee71 100644
--- a/apps/playback.c
+++ b/apps/playback.c
@@ -744,16 +744,25 @@
/* 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 @@
#ifdef PLAYBACK_VOICE
voice_stop();
#endif
+ buffer_release_buffer(0);
}
/* Resume playback if paused */
@@ -3441,7 +3451,7 @@
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 @@
|| !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 @@
talk_buffer_steal();
buffer_state = AUDIOBUF_STATE_TRASHED;
}
-
- buf = audiobuf;
- end = audiobufend;
+ buf = buffer_get_buffer(buffer_size);
}
else
{
@@ -3485,14 +3493,18 @@
/* 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 @@
/* 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 ea87180..793055f 100644
--- a/apps/playback.h
+++ b/apps/playback.h
@@ -75,7 +75,6 @@
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 564cd03..8334260 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -533,13 +533,7 @@
{
/* 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 @@
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 @@
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 803fba9..43c0c01 100644
--- a/apps/playlist_viewer.c
+++ b/apps/playlist_viewer.c
@@ -493,9 +493,6 @@
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 50fbb37..32b77ad 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -979,14 +979,8 @@
*/
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 a53df90..e2a5771 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -828,12 +828,14 @@
#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 98ca15b..af7b817 100644
--- a/apps/plugins/vbrfix.c
+++ b/apps/plugins/vbrfix.c
@@ -157,14 +157,15 @@
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 8a832e4..407a7e5 100644
--- a/apps/recorder/pcm_record.c
+++ b/apps/recorder/pcm_record.c
@@ -1643,14 +1643,12 @@
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 6aa7709..0a491c5 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -107,7 +107,7 @@
/* 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 @@
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 @@
#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 8c0f1f3..9fd6fb0 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 @@
#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 @@
/* 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 @@
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 @@
}
#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 @@
* 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 @@
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 @@
}
-/* 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 @@
buffered_id[i] = -1;
#endif
- thumbnail_buf_used = 0;
p_silence = NULL; /* pause clip not accessible */
+ voicebuf = NULL;
}
@@ -655,12 +681,11 @@
#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 @@
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 @@
voicefile_size = 0;
}
+ alloc_thumbnail_buf();
close(filehandle); /* close again, this was just to detect presence */
filehandle = -1;
}
@@ -703,11 +732,25 @@
#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 @@
#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 @@
#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 a2a9f44..e170214 100644
--- a/apps/talk.h
+++ b/apps/talk.h
@@ -80,6 +80,7 @@
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 c317cec..2168087 100644
--- a/firmware/buffer.c
+++ b/firmware/buffer.c
@@ -19,19 +19,33 @@
*
****************************************************************************/
#include <stdio.h>
+#include <stdint.h>
+#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 @@
{
/* 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 08fe509..d114a6a 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -862,22 +862,26 @@
* 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 @@
/* 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 910791c..6757bf1 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 @@
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 18f53f0..bdf91bc 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 0ac937d..6beeeb6 100644
--- a/firmware/include/dircache.h
+++ b/firmware/include/dircache.h
@@ -23,6 +23,7 @@
#include "config.h"
#include "dir_uncached.h"
+#include <string.h> /* size_t */
#ifdef HAVE_DIRCACHE
@@ -65,7 +66,7 @@
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 078a4e9..9b6f4fe 100644
--- a/firmware/rolo.c
+++ b/firmware/rolo.c
@@ -99,6 +99,7 @@
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 @@
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 @@
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 @@
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 @@
#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 @@
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 @@
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 @@
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;