summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/filetree.c1
-rw-r--r--apps/main.c11
-rw-r--r--apps/menus/main_menu.c4
-rw-r--r--apps/misc.c3
-rw-r--r--apps/mp3data.c41
-rw-r--r--apps/mp3data.h30
-rw-r--r--apps/mpeg.c89
-rw-r--r--apps/playback.c45
-rw-r--r--apps/playback.h1
-rw-r--r--apps/playlist.c18
-rw-r--r--apps/playlist_viewer.c3
-rw-r--r--apps/plugin.c8
-rw-r--r--apps/plugin.h8
-rw-r--r--apps/plugins/vbrfix.c5
-rw-r--r--apps/recorder/pcm_record.c2
-rw-r--r--apps/tagcache.c8
-rw-r--r--apps/talk.c111
-rw-r--r--apps/talk.h1
18 files changed, 231 insertions, 158 deletions
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 @@ 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 0b566b5..9cb7245 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 6ee7ba4..c5758d1 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 fef55d5..d74fe73 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 9fed727..53f13f4 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 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 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 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 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 fe9bd57..3f6ee71 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 ea87180..793055f 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 564cd03..8334260 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 803fba9..43c0c01 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 50fbb37..32b77ad 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 a53df90..e2a5771 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 98ca15b..af7b817 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 8a832e4..407a7e5 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 6aa7709..0a491c5 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 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 @@ 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,8 +732,22 @@ 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;
}
@@ -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 a2a9f44..e170214 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 */