forked from len0rd/rockbox
Bunch of playback bugs fixed including next/prev/select track,
pausing, faster ui response, ... git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6641 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
a501277a1c
commit
fe468b1149
2 changed files with 30 additions and 32 deletions
|
|
@ -68,7 +68,7 @@ static volatile bool paused;
|
||||||
#define CODEC_WAV "/.rockbox/codecs/codecwav.rock";
|
#define CODEC_WAV "/.rockbox/codecs/codecwav.rock";
|
||||||
|
|
||||||
#define AUDIO_WATERMARK 0x70000
|
#define AUDIO_WATERMARK 0x70000
|
||||||
#define AUDIO_FILE_CHUNK (1024*512)
|
#define AUDIO_FILE_CHUNK (1024*32)
|
||||||
|
|
||||||
#define AUDIO_PLAY 1
|
#define AUDIO_PLAY 1
|
||||||
#define AUDIO_STOP 2
|
#define AUDIO_STOP 2
|
||||||
|
|
@ -107,9 +107,6 @@ static const char codec_thread_name[] = "codec";
|
||||||
/* Is file buffer currently being refilled? */
|
/* Is file buffer currently being refilled? */
|
||||||
static volatile bool filling;
|
static volatile bool filling;
|
||||||
|
|
||||||
/* Interrupts buffer filling. */
|
|
||||||
static volatile bool interrupt;
|
|
||||||
|
|
||||||
/* Ring buffer where tracks and codecs are loaded. */
|
/* Ring buffer where tracks and codecs are loaded. */
|
||||||
char *codecbuf;
|
char *codecbuf;
|
||||||
|
|
||||||
|
|
@ -423,7 +420,7 @@ void audio_fill_file_buffer(void)
|
||||||
/* Give codecs some processing time. */
|
/* Give codecs some processing time. */
|
||||||
yield_codecs();
|
yield_codecs();
|
||||||
|
|
||||||
if (interrupt) {
|
if (!queue_empty(&audio_queue)) {
|
||||||
logf("Filling interrupted");
|
logf("Filling interrupted");
|
||||||
close(current_fd);
|
close(current_fd);
|
||||||
current_fd = -1;
|
current_fd = -1;
|
||||||
|
|
@ -543,7 +540,7 @@ bool loadcodec(const char *trackname, bool start_play)
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < size) {
|
while (i < size) {
|
||||||
yield_codecs();
|
yield_codecs();
|
||||||
if (interrupt) {
|
if (!queue_empty(&audio_queue)) {
|
||||||
logf("Buffering interrupted");
|
logf("Buffering interrupted");
|
||||||
close(fd);
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -610,10 +607,12 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
|
||||||
}
|
}
|
||||||
tracks[track_widx].filebuf = &codecbuf[buf_widx];
|
tracks[track_widx].filebuf = &codecbuf[buf_widx];
|
||||||
|
|
||||||
logf("%s", trackname);
|
//logf("%s", trackname);
|
||||||
logf("Buffering track:%d/%d", track_widx, track_ridx);
|
logf("Buffering track:%d/%d", track_widx, track_ridx);
|
||||||
|
|
||||||
if (interrupt) {
|
if (!queue_empty(&audio_queue)) {
|
||||||
|
logf("Interrupted!");
|
||||||
|
ci.stop_codec = true;
|
||||||
close(fd);
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -637,10 +636,12 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
|
||||||
} else {
|
} else {
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
logf("T:%s", tracks[track_widx].id3.title);
|
logf("T:%s", tracks[track_widx].id3.title);
|
||||||
logf("L:%d", tracks[track_widx].id3.length);
|
logf("L:%d", tracks[track_widx].id3.length);
|
||||||
logf("O:%d", tracks[track_widx].id3.first_frame_offset);
|
logf("O:%d", tracks[track_widx].id3.first_frame_offset);
|
||||||
logf("F:%d", tracks[track_widx].id3.frequency);
|
logf("F:%d", tracks[track_widx].id3.frequency);
|
||||||
|
*/
|
||||||
tracks[track_widx].taginfo_ready = true;
|
tracks[track_widx].taginfo_ready = true;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
|
|
@ -715,12 +716,13 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
track_changed = true;
|
||||||
track_count++;
|
track_count++;
|
||||||
i = tracks[track_widx].filepos;
|
i = tracks[track_widx].filepos;
|
||||||
while (i < size) {
|
while (i < size) {
|
||||||
/* Give codecs some processing time to prevent glitches. */
|
/* Give codecs some processing time to prevent glitches. */
|
||||||
yield_codecs();
|
yield_codecs();
|
||||||
if (interrupt) {
|
if (!queue_empty(&audio_queue)) {
|
||||||
logf("Buffering interrupted");
|
logf("Buffering interrupted");
|
||||||
close(fd);
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -734,6 +736,7 @@ bool audio_load_track(int offset, bool start_play, int peek_offset)
|
||||||
copy_n = MIN((int)fill_bytesleft, copy_n);
|
copy_n = MIN((int)fill_bytesleft, copy_n);
|
||||||
rc = read(fd, &codecbuf[buf_widx], copy_n);
|
rc = read(fd, &codecbuf[buf_widx], copy_n);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
logf("File error!");
|
||||||
close(fd);
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -782,10 +785,9 @@ void audio_insert_tracks(int offset, bool start_playing)
|
||||||
|
|
||||||
void audio_play_start(int offset)
|
void audio_play_start(int offset)
|
||||||
{
|
{
|
||||||
memset(&tracks, 0, sizeof(struct track_info));
|
memset(&tracks, 0, sizeof(struct track_info) * MAX_TRACK);
|
||||||
sound_set(SOUND_VOLUME, global_settings.volume);
|
sound_set(SOUND_VOLUME, global_settings.volume);
|
||||||
track_count = 0;
|
track_count = 0;
|
||||||
track_changed = true;
|
|
||||||
track_widx = 0;
|
track_widx = 0;
|
||||||
track_ridx = 0;
|
track_ridx = 0;
|
||||||
buf_ridx = 0;
|
buf_ridx = 0;
|
||||||
|
|
@ -808,12 +810,13 @@ void audio_check_buffer(void)
|
||||||
|
|
||||||
/* Fill buffer as full as possible for cross-fader. */
|
/* Fill buffer as full as possible for cross-fader. */
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
if (cur_ti->id3.length - cur_ti->id3.elapsed < 20000)
|
if (cur_ti->id3.length - cur_ti->id3.elapsed < 20000 && playing)
|
||||||
pcm_set_boost_mode(true);
|
pcm_set_boost_mode(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Start buffer filling as necessary. */
|
/* Start buffer filling as necessary. */
|
||||||
if (codecbufused > AUDIO_WATERMARK || interrupt || !playing)
|
if (codecbufused > AUDIO_WATERMARK || !queue_empty(&audio_queue)
|
||||||
|
|| !playing || ci.stop_codec || ci.reload_codec)
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
filling = true;
|
filling = true;
|
||||||
|
|
@ -915,7 +918,7 @@ void audio_change_track(void)
|
||||||
|
|
||||||
bool codec_request_next_track_callback(void)
|
bool codec_request_next_track_callback(void)
|
||||||
{
|
{
|
||||||
if (ci.stop_codec || !playing)
|
if (ci.stop_codec || !playing || !queue_empty(&audio_queue))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
logf("Request new track");
|
logf("Request new track");
|
||||||
|
|
@ -989,21 +992,20 @@ void audio_thread(void)
|
||||||
yield();
|
yield();
|
||||||
audio_check_buffer();
|
audio_check_buffer();
|
||||||
|
|
||||||
queue_wait_w_tmo(&audio_queue, &ev, 0);
|
queue_wait_w_tmo(&audio_queue, &ev, 10);
|
||||||
switch (ev.id) {
|
switch (ev.id) {
|
||||||
case AUDIO_PLAY:
|
case AUDIO_PLAY:
|
||||||
interrupt = false;
|
|
||||||
ci.stop_codec = true;
|
ci.stop_codec = true;
|
||||||
ci.reload_codec = false;
|
ci.reload_codec = false;
|
||||||
ci.seek_time = 0;
|
ci.seek_time = 0;
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
pcm_play_stop();
|
pcm_play_stop();
|
||||||
#endif
|
#endif
|
||||||
paused = false;
|
|
||||||
audio_play_start((int)ev.data);
|
audio_play_start((int)ev.data);
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case AUDIO_STOP:
|
case AUDIO_STOP:
|
||||||
|
paused = false;
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
pcm_play_stop();
|
pcm_play_stop();
|
||||||
pcm_play_pause(true);
|
pcm_play_pause(true);
|
||||||
|
|
@ -1092,12 +1094,11 @@ void codec_thread(void)
|
||||||
|
|
||||||
if (playing && !ci.stop_codec && !ci.reload_codec) {
|
if (playing && !ci.stop_codec && !ci.reload_codec) {
|
||||||
audio_change_track();
|
audio_change_track();
|
||||||
} else if (ci.reload_codec) {
|
continue ;
|
||||||
interrupt = true;
|
} else if (ci.stop_codec) {
|
||||||
} else {
|
//playing = false;
|
||||||
playing = false;
|
|
||||||
}
|
}
|
||||||
queue_post(&audio_queue, AUDIO_CODEC_DONE, (void *)status);
|
//queue_post(&audio_queue, AUDIO_CODEC_DONE, (void *)status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1146,7 +1147,6 @@ void audio_play(int offset)
|
||||||
{
|
{
|
||||||
logf("audio_play");
|
logf("audio_play");
|
||||||
ci.stop_codec = true;
|
ci.stop_codec = true;
|
||||||
playing = false;
|
|
||||||
#ifndef SIMULATOR
|
#ifndef SIMULATOR
|
||||||
pcm_play_pause(true);
|
pcm_play_pause(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1157,6 +1157,7 @@ void audio_stop(void)
|
||||||
{
|
{
|
||||||
logf("audio_stop");
|
logf("audio_stop");
|
||||||
playing = false;
|
playing = false;
|
||||||
|
paused = false;
|
||||||
ci.stop_codec = true;
|
ci.stop_codec = true;
|
||||||
if (current_fd) {
|
if (current_fd) {
|
||||||
close(current_fd);
|
close(current_fd);
|
||||||
|
|
@ -1196,7 +1197,6 @@ void audio_next(void)
|
||||||
|
|
||||||
/* Detect if disk is spinning.. */
|
/* Detect if disk is spinning.. */
|
||||||
if (filling) {
|
if (filling) {
|
||||||
interrupt = true;
|
|
||||||
ci.stop_codec = true;
|
ci.stop_codec = true;
|
||||||
playlist_next(1);
|
playlist_next(1);
|
||||||
queue_post(&audio_queue, AUDIO_PLAY, 0);
|
queue_post(&audio_queue, AUDIO_PLAY, 0);
|
||||||
|
|
@ -1217,7 +1217,6 @@ void audio_prev(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (filling) {
|
if (filling) {
|
||||||
interrupt = true;
|
|
||||||
ci.stop_codec = true;
|
ci.stop_codec = true;
|
||||||
playlist_next(-1);
|
playlist_next(-1);
|
||||||
queue_post(&audio_queue, AUDIO_PLAY, 0);
|
queue_post(&audio_queue, AUDIO_PLAY, 0);
|
||||||
|
|
@ -1398,7 +1397,6 @@ void audio_init(void)
|
||||||
//codecbuflen = 2*512*1024;
|
//codecbuflen = 2*512*1024;
|
||||||
codecbufused = 0;
|
codecbufused = 0;
|
||||||
filling = false;
|
filling = false;
|
||||||
interrupt = false;
|
|
||||||
codecbuf = &audiobuf[MALLOC_BUFSIZE];
|
codecbuf = &audiobuf[MALLOC_BUFSIZE];
|
||||||
playing = false;
|
playing = false;
|
||||||
paused = false;
|
paused = false;
|
||||||
|
|
|
||||||
|
|
@ -234,7 +234,7 @@ void pcm_play_stop(void)
|
||||||
pcmbuf_unplayed_bytes = 0;
|
pcmbuf_unplayed_bytes = 0;
|
||||||
next_start = NULL;
|
next_start = NULL;
|
||||||
next_size = 0;
|
next_size = 0;
|
||||||
pcm_boost(false);
|
pcm_set_boost_mode(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcm_play_pause(bool play)
|
void pcm_play_pause(bool play)
|
||||||
|
|
@ -252,6 +252,7 @@ void pcm_play_pause(bool play)
|
||||||
IIS2CONFIG = 0x800;
|
IIS2CONFIG = 0x800;
|
||||||
pcm_paused = true;
|
pcm_paused = true;
|
||||||
}
|
}
|
||||||
|
pcm_boost(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pcm_is_playing(void)
|
bool pcm_is_playing(void)
|
||||||
|
|
@ -349,8 +350,7 @@ void pcm_watermark_callback(int bytes_left)
|
||||||
void pcm_set_boost_mode(bool state)
|
void pcm_set_boost_mode(bool state)
|
||||||
{
|
{
|
||||||
boost_mode = state;
|
boost_mode = state;
|
||||||
if (boost_mode)
|
pcm_boost(state);
|
||||||
pcm_boost(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void audiobuffer_add_event(void (*event_handler)(void))
|
void audiobuffer_add_event(void (*event_handler)(void))
|
||||||
|
|
@ -385,7 +385,7 @@ bool pcm_is_lowdata(void)
|
||||||
|
|
||||||
void pcm_crossfade_start(void)
|
void pcm_crossfade_start(void)
|
||||||
{
|
{
|
||||||
if (audiobuffer_free > CHUNK_SIZE * 4) {
|
if (audiobuffer_free > CHUNK_SIZE * 4 || !crossfade_enabled) {
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
pcm_boost(true);
|
pcm_boost(true);
|
||||||
|
|
@ -433,7 +433,7 @@ bool audiobuffer_insert(char *buf, size_t length)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (length > 0) {
|
while (length > 0) {
|
||||||
if (crossfade_enabled && crossfade_active) {
|
if (crossfade_active) {
|
||||||
copy_n = MIN(length, PCMBUF_SIZE - (unsigned int)crossfade_pos);
|
copy_n = MIN(length, PCMBUF_SIZE - (unsigned int)crossfade_pos);
|
||||||
|
|
||||||
crossfade((short *)&audiobuffer[crossfade_pos],
|
crossfade((short *)&audiobuffer[crossfade_pos],
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue