forked from len0rd/rockbox
PCM buffering fixes. Made a temporary workaround for playback glitch
bug (see the patch). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7049 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
8d3855eb53
commit
3eb962d13b
4 changed files with 87 additions and 72 deletions
|
|
@ -277,6 +277,9 @@ int codec_load_file(const char *plugin)
|
|||
int fd;
|
||||
int rc;
|
||||
|
||||
/* zero out codec buffer to ensure a properly zeroed bss area */
|
||||
memset(codecbuf, 0, CODEC_SIZE);
|
||||
|
||||
fd = open(plugin, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
snprintf(msgbuf, sizeof(msgbuf)-1, "Couldn't load codec: %s", plugin);
|
||||
|
|
|
|||
|
|
@ -39,12 +39,6 @@ void abort(void) {
|
|||
|
||||
|
||||
#define INPUT_CHUNK_SIZE 8192
|
||||
#define OUTPUT_BUFFER_SIZE 65536 /* Must be an integer multiple of 4. */
|
||||
|
||||
unsigned char OutputBuffer[OUTPUT_BUFFER_SIZE];
|
||||
unsigned char *OutputPtr;
|
||||
unsigned char *GuardPtr = NULL;
|
||||
const unsigned char *OutputBufferEnd = OutputBuffer + OUTPUT_BUFFER_SIZE;
|
||||
|
||||
mad_fixed_t mad_frame_overlap[2][32][18] IDATA_ATTR;
|
||||
unsigned char mad_main_data[MAD_BUFFER_MDLEN] IDATA_ATTR;
|
||||
|
|
@ -115,7 +109,6 @@ enum codec_status codec_start(struct codec_api* api)
|
|||
|
||||
first_frame = false;
|
||||
file_end = 0;
|
||||
OutputPtr = OutputBuffer;
|
||||
|
||||
while (!*ci->taginfo_ready)
|
||||
ci->yield();
|
||||
|
|
@ -195,7 +188,7 @@ enum codec_status codec_start(struct codec_api* api)
|
|||
}
|
||||
else if(MAD_RECOVERABLE(Stream.error))
|
||||
{
|
||||
if(Stream.error!=MAD_ERROR_LOSTSYNC || Stream.this_frame!=GuardPtr)
|
||||
if(Stream.error!=MAD_ERROR_LOSTSYNC)
|
||||
{
|
||||
// rb->splash(HZ*1, true, "Recoverable...!");
|
||||
}
|
||||
|
|
@ -209,9 +202,9 @@ enum codec_status codec_start(struct codec_api* api)
|
|||
Status=1;
|
||||
break;
|
||||
}
|
||||
break ;
|
||||
}
|
||||
if (Stream.next_frame)
|
||||
ci->advance_buffer_loc((void *)Stream.next_frame);
|
||||
|
||||
file_end = false;
|
||||
/* ?? Do we need the timer module? */
|
||||
// mad_timer_add(&Timer,Frame.header.duration);
|
||||
|
|
@ -222,7 +215,7 @@ enum codec_status codec_start(struct codec_api* api)
|
|||
/* We skip start_skip number of samples here, this should only happen for
|
||||
very first frame in the stream. */
|
||||
/* TODO: possible for start_skip to exceed one frames worth of samples? */
|
||||
|
||||
|
||||
if (MAD_NCHANNELS(&Frame.header) == 2) {
|
||||
if (current_stereo_mode != STEREO_NONINTERLEAVED) {
|
||||
ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_NONINTERLEAVED);
|
||||
|
|
@ -241,6 +234,11 @@ enum codec_status codec_start(struct codec_api* api)
|
|||
}
|
||||
start_skip = 0; /* not very elegant, and might want to keep this value */
|
||||
|
||||
if (Stream.next_frame)
|
||||
ci->advance_buffer_loc((void *)Stream.next_frame);
|
||||
else
|
||||
ci->advance_buffer(size);
|
||||
|
||||
samplesdone += Synth.pcm.length;
|
||||
samplecount -= Synth.pcm.length;
|
||||
ci->set_elapsed(samplesdone / (frequency_divider / 10));
|
||||
|
|
|
|||
|
|
@ -659,12 +659,12 @@ void audio_fill_file_buffer(void)
|
|||
buf_widx -= codecbuflen;
|
||||
i += rc;
|
||||
tracks[track_widx].available += rc;
|
||||
tracks[track_widx].filerem -= rc;
|
||||
tracks[track_widx].filepos += rc;
|
||||
codecbufused += rc;
|
||||
fill_bytesleft -= rc;
|
||||
}
|
||||
|
||||
tracks[track_widx].filerem -= i;
|
||||
tracks[track_widx].filepos += i;
|
||||
/*logf("Filled:%d/%d", tracks[track_widx].available,
|
||||
tracks[track_widx].filerem);*/
|
||||
}
|
||||
|
|
@ -890,26 +890,29 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
|
|||
|
||||
/* Starting playback from an offset is only support in MPA at the moment */
|
||||
if (offset > 0) {
|
||||
if ((tracks[track_widx].id3.codectype==AFMT_MPA_L2) ||
|
||||
(tracks[track_widx].id3.codectype==AFMT_MPA_L3)) {
|
||||
lseek(fd, offset, SEEK_SET);
|
||||
tracks[track_widx].id3.offset = offset;
|
||||
mp3_set_elapsed(&tracks[track_widx].id3);
|
||||
tracks[track_widx].filepos = offset;
|
||||
tracks[track_widx].filerem = tracks[track_widx].filesize - offset;
|
||||
ci.curpos = offset;
|
||||
tracks[track_widx].start_pos = offset;
|
||||
}
|
||||
else if (tracks[track_widx].id3.codectype==AFMT_WAVPACK) {
|
||||
lseek(fd, offset, SEEK_SET);
|
||||
tracks[track_widx].id3.offset = offset;
|
||||
tracks[track_widx].id3.elapsed = tracks[track_widx].id3.length / 2;
|
||||
tracks[track_widx].filepos = offset;
|
||||
tracks[track_widx].filerem = tracks[track_widx].filesize - offset;
|
||||
ci.curpos = offset;
|
||||
tracks[track_widx].start_pos = offset;
|
||||
}
|
||||
}
|
||||
switch (tracks[track_widx].id3.codectype) {
|
||||
case AFMT_MPA_L2:
|
||||
case AFMT_MPA_L3:
|
||||
lseek(fd, offset, SEEK_SET);
|
||||
tracks[track_widx].id3.offset = offset;
|
||||
mp3_set_elapsed(&tracks[track_widx].id3);
|
||||
tracks[track_widx].filepos = offset;
|
||||
tracks[track_widx].filerem = tracks[track_widx].filesize - offset;
|
||||
ci.curpos = offset;
|
||||
tracks[track_widx].start_pos = offset;
|
||||
break;
|
||||
|
||||
case AFMT_WAVPACK:
|
||||
lseek(fd, offset, SEEK_SET);
|
||||
tracks[track_widx].id3.offset = offset;
|
||||
tracks[track_widx].id3.elapsed = tracks[track_widx].id3.length / 2;
|
||||
tracks[track_widx].filepos = offset;
|
||||
tracks[track_widx].filerem = tracks[track_widx].filesize - offset;
|
||||
ci.curpos = offset;
|
||||
tracks[track_widx].start_pos = offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (start_play) {
|
||||
track_count++;
|
||||
|
|
@ -1795,6 +1798,8 @@ void audio_init(void)
|
|||
track_buffer_callback = NULL;
|
||||
track_unbuffer_callback = NULL;
|
||||
track_changed_callback = NULL;
|
||||
/* Just to prevent cur_ti never be anything random. */
|
||||
cur_ti = &tracks[0];
|
||||
|
||||
logf("abuf:%0x", PCMBUF_SIZE);
|
||||
logf("fbuf:%0x", codecbuflen);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue